diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedAttributes.txt b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedAttributes.txt
index 4437f6a62..e3e5357ee 100644
--- a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedAttributes.txt
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedAttributes.txt
@@ -1 +1,2 @@
T:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute
+T:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Header.txt b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Header.txt
index 7dae5f0c9..085737f4f 100644
--- a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Header.txt
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Header.txt
@@ -17,5 +17,8 @@
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
#pragma warning disable CA1063 // Implement IDisposable Correctly
#pragma warning disable CA1816 // Dispose methods should call SuppressFinalize
+#pragma warning disable CA1721 // Property names should not match get methods
+#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
+#pragma warning disable CA1720 // Identifier contains type name
#pragma warning disable CS0436 // Type conflicts with imported type
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Ref.Standard.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Ref.Standard.cs
index 205d1e022..0e97b09dd 100644
--- a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Ref.Standard.cs
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/Ref.Standard.cs
@@ -17,6 +17,9 @@
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
#pragma warning disable CA1063 // Implement IDisposable Correctly
#pragma warning disable CA1816 // Dispose methods should call SuppressFinalize
+#pragma warning disable CA1721 // Property names should not match get methods
+#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
+#pragma warning disable CA1720 // Identifier contains type name
#pragma warning disable CS0436 // Type conflicts with imported type
namespace System.Web
@@ -864,3 +867,318 @@ public enum SessionStateMode
StateServer = 2,
}
}
+namespace System.Web.UI
+{
+ public partial class HtmlTextWriter : System.IO.TextWriter
+ {
+ public const string DefaultTabString = "\t";
+ public const char DoubleQuoteChar = '"';
+ public const string EndTagLeftChars = "";
+ public const char EqualsChar = '=';
+ public const string EqualsDoubleQuoteString = "=\"";
+ public const string SelfClosingChars = " /";
+ public const string SelfClosingTagEnd = " />";
+ public const char SemicolonChar = ';';
+ public const char SingleQuoteChar = '\'';
+ public const char SlashChar = '/';
+ public const char SpaceChar = ' ';
+ public const char StyleEqualsChar = ':';
+ public const char TagLeftChar = '<';
+ public const char TagRightChar = '>';
+ public HtmlTextWriter(System.IO.TextWriter writer) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public HtmlTextWriter(System.IO.TextWriter writer, string tabString) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override System.Text.Encoding Encoding { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
+ public int Indent { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} set { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
+ public System.IO.TextWriter InnerWriter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
+ public override string NewLine { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} set { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
+ protected System.Web.UI.HtmlTextWriterTag TagKey { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} set { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
+ protected string TagName { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} set { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
+ public virtual void AddAttribute(string name, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void AddAttribute(string name, string value, bool fEndode) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual void AddAttribute(string name, string value, System.Web.UI.HtmlTextWriterAttribute key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void AddAttribute(System.Web.UI.HtmlTextWriterAttribute key, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void AddAttribute(System.Web.UI.HtmlTextWriterAttribute key, string value, bool fEncode) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void AddStyleAttribute(string name, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual void AddStyleAttribute(string name, string value, System.Web.UI.HtmlTextWriterStyle key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle key, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void BeginRender() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Close() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected string EncodeAttributeValue(string value, bool fEncode) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual string EncodeAttributeValue(System.Web.UI.HtmlTextWriterAttribute attrKey, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected string EncodeUrl(string url) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void EndRender() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual void FilterAttributes() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Flush() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected System.Web.UI.HtmlTextWriterAttribute GetAttributeKey(string attrName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected string GetAttributeName(System.Web.UI.HtmlTextWriterAttribute attrKey) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected System.Web.UI.HtmlTextWriterStyle GetStyleKey(string styleName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected string GetStyleName(System.Web.UI.HtmlTextWriterStyle styleKey) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual System.Web.UI.HtmlTextWriterTag GetTagKey(string tagName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual string GetTagName(System.Web.UI.HtmlTextWriterTag tagKey) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected bool IsAttributeDefined(System.Web.UI.HtmlTextWriterAttribute key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected bool IsAttributeDefined(System.Web.UI.HtmlTextWriterAttribute key, out string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected bool IsStyleAttributeDefined(System.Web.UI.HtmlTextWriterStyle key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected bool IsStyleAttributeDefined(System.Web.UI.HtmlTextWriterStyle key, out string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual bool IsValidFormAttribute(string attribute) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual bool OnAttributeRender(string name, string value, System.Web.UI.HtmlTextWriterAttribute key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual bool OnStyleAttributeRender(string name, string value, System.Web.UI.HtmlTextWriterStyle key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual bool OnTagRender(string name, System.Web.UI.HtmlTextWriterTag key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual void OutputTabs() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected string PopEndTag() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected void PushEndTag(string endTag) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected static void RegisterAttribute(string name, System.Web.UI.HtmlTextWriterAttribute key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected static void RegisterStyle(string name, System.Web.UI.HtmlTextWriterStyle key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected static void RegisterTag(string name, System.Web.UI.HtmlTextWriterTag key) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual string RenderAfterContent() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual string RenderAfterTag() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual string RenderBeforeContent() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected virtual string RenderBeforeTag() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void RenderBeginTag(string tagName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void RenderBeginTag(System.Web.UI.HtmlTextWriterTag tagKey) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void RenderEndTag() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(bool value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(char value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(char[] buffer) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(char[] buffer, int index, int count) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(double value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(int value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(long value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(object value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(float value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(string format, object arg0) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(string format, object arg0, object arg1) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void Write(string format, params object[] arg) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteAttribute(string name, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteAttribute(string name, string value, bool fEncode) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteBeginTag(string tagName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteBreak() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteEncodedText(string text) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteEncodedUrl(string url) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteEncodedUrlParameter(string urlText) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteEndTag(string tagName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteFullBeginTag(string tagName) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(bool value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(char value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(char[] buffer) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(char[] buffer, int index, int count) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(double value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(int value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(long value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(object value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(float value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(string format, object arg0) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(string format, object arg0, object arg1) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(string format, params object[] arg) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public override void WriteLine(uint value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public void WriteLineNoTabs(string s) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteStyleAttribute(string name, string value) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ public virtual void WriteStyleAttribute(string name, string value, bool fEncode) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ protected void WriteUrlEncodedString(string text, bool argument) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
+ }
+ public enum HtmlTextWriterAttribute
+ {
+ Abbr = 40,
+ Accesskey = 0,
+ Align = 1,
+ Alt = 2,
+ AutoComplete = 41,
+ Axis = 42,
+ Background = 3,
+ Bgcolor = 4,
+ Border = 5,
+ Bordercolor = 6,
+ Cellpadding = 7,
+ Cellspacing = 8,
+ Checked = 9,
+ Class = 10,
+ Cols = 11,
+ Colspan = 12,
+ Content = 43,
+ Coords = 44,
+ DesignerRegion = 45,
+ Dir = 46,
+ Disabled = 13,
+ For = 14,
+ Headers = 47,
+ Height = 15,
+ Href = 16,
+ Id = 17,
+ Longdesc = 48,
+ Maxlength = 18,
+ Multiple = 19,
+ Name = 20,
+ Nowrap = 21,
+ Onchange = 22,
+ Onclick = 23,
+ ReadOnly = 24,
+ Rel = 49,
+ Rows = 25,
+ Rowspan = 26,
+ Rules = 27,
+ Scope = 50,
+ Selected = 28,
+ Shape = 51,
+ Size = 29,
+ Src = 30,
+ Style = 31,
+ Tabindex = 32,
+ Target = 33,
+ Title = 34,
+ Type = 35,
+ Usemap = 52,
+ Valign = 36,
+ Value = 37,
+ VCardName = 53,
+ Width = 38,
+ Wrap = 39,
+ }
+ public enum HtmlTextWriterStyle
+ {
+ BackgroundColor = 0,
+ BackgroundImage = 1,
+ BorderCollapse = 2,
+ BorderColor = 3,
+ BorderStyle = 4,
+ BorderWidth = 5,
+ Color = 6,
+ Cursor = 16,
+ Direction = 17,
+ Display = 18,
+ Filter = 19,
+ FontFamily = 7,
+ FontSize = 8,
+ FontStyle = 9,
+ FontVariant = 20,
+ FontWeight = 10,
+ Height = 11,
+ Left = 21,
+ ListStyleImage = 14,
+ ListStyleType = 15,
+ Margin = 22,
+ MarginBottom = 23,
+ MarginLeft = 24,
+ MarginRight = 25,
+ MarginTop = 26,
+ Overflow = 27,
+ OverflowX = 28,
+ OverflowY = 29,
+ Padding = 30,
+ PaddingBottom = 31,
+ PaddingLeft = 32,
+ PaddingRight = 33,
+ PaddingTop = 34,
+ Position = 35,
+ TextAlign = 36,
+ TextDecoration = 12,
+ TextOverflow = 38,
+ Top = 39,
+ VerticalAlign = 37,
+ Visibility = 40,
+ WhiteSpace = 41,
+ Width = 13,
+ ZIndex = 42,
+ }
+ public enum HtmlTextWriterTag
+ {
+ A = 1,
+ Acronym = 2,
+ Address = 3,
+ Area = 4,
+ B = 5,
+ Base = 6,
+ Basefont = 7,
+ Bdo = 8,
+ Bgsound = 9,
+ Big = 10,
+ Blockquote = 11,
+ Body = 12,
+ Br = 13,
+ Button = 14,
+ Caption = 15,
+ Center = 16,
+ Cite = 17,
+ Code = 18,
+ Col = 19,
+ Colgroup = 20,
+ Dd = 21,
+ Del = 22,
+ Dfn = 23,
+ Dir = 24,
+ Div = 25,
+ Dl = 26,
+ Dt = 27,
+ Em = 28,
+ Embed = 29,
+ Fieldset = 30,
+ Font = 31,
+ Form = 32,
+ Frame = 33,
+ Frameset = 34,
+ H1 = 35,
+ H2 = 36,
+ H3 = 37,
+ H4 = 38,
+ H5 = 39,
+ H6 = 40,
+ Head = 41,
+ Hr = 42,
+ Html = 43,
+ I = 44,
+ Iframe = 45,
+ Img = 46,
+ Input = 47,
+ Ins = 48,
+ Isindex = 49,
+ Kbd = 50,
+ Label = 51,
+ Legend = 52,
+ Li = 53,
+ Link = 54,
+ Map = 55,
+ Marquee = 56,
+ Menu = 57,
+ Meta = 58,
+ Nobr = 59,
+ Noframes = 60,
+ Noscript = 61,
+ Object = 62,
+ Ol = 63,
+ Option = 64,
+ P = 65,
+ Param = 66,
+ Pre = 67,
+ Q = 68,
+ Rt = 69,
+ Ruby = 70,
+ S = 71,
+ Samp = 72,
+ Script = 73,
+ Select = 74,
+ Small = 75,
+ Span = 76,
+ Strike = 77,
+ Strong = 78,
+ Style = 79,
+ Sub = 80,
+ Sup = 81,
+ Table = 82,
+ Tbody = 83,
+ Td = 84,
+ Textarea = 85,
+ Tfoot = 86,
+ Th = 87,
+ Thead = 88,
+ Title = 89,
+ Tr = 90,
+ Tt = 91,
+ U = 92,
+ Ul = 93,
+ Unknown = 0,
+ Var = 94,
+ Wbr = 95,
+ Xml = 96,
+ }
+}
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/TypeForwards.Framework.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/TypeForwards.Framework.cs
index 8d529cc2d..fce5f3f07 100644
--- a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/TypeForwards.Framework.cs
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/TypeForwards.Framework.cs
@@ -17,6 +17,9 @@
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
#pragma warning disable CA1063 // Implement IDisposable Correctly
#pragma warning disable CA1816 // Dispose methods should call SuppressFinalize
+#pragma warning disable CA1721 // Property names should not match get methods
+#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
+#pragma warning disable CA1720 // Identifier contains type name
#pragma warning disable CS0436 // Type conflicts with imported type
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.HttpApplication))]
@@ -70,3 +73,7 @@
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Hosting.HostingEnvironment))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.SessionState.HttpSessionState))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.SessionState.SessionStateMode))]
+[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.UI.HtmlTextWriter))]
+[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.UI.HtmlTextWriterAttribute))]
+[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.UI.HtmlTextWriterStyle))]
+[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.UI.HtmlTextWriterTag))]
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseWrapper.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseWrapper.cs
index 19603596c..277430e1d 100644
--- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseWrapper.cs
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseWrapper.cs
@@ -5,7 +5,6 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
-using Microsoft.AspNetCore.Http;
namespace System.Web
{
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/HttpValueCollection.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/HttpValueCollection.cs
index 863071fe3..722e3ca31 100644
--- a/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/HttpValueCollection.cs
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/HttpValueCollection.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Web;
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/UI/CssTextWriter.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/CssTextWriter.cs
new file mode 100644
index 000000000..65765e371
--- /dev/null
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/CssTextWriter.cs
@@ -0,0 +1,234 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.IO;
+
+namespace System.Web.UI;
+
+///
+/// Derived TextWriter that provides CSS rendering API.
+///
+internal sealed class CssTextWriter
+{
+ private static readonly Dictionary attrKeyLookupTable = new(StringComparer.OrdinalIgnoreCase);
+ private static readonly List attrNameLookupArray = new();
+
+ [Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1810:Initialize reference type static fields inline", Justification = "")]
+ static CssTextWriter()
+ {
+ // register known style attributes, HtmlTextWriterStyle.Length
+ RegisterAttribute("background-color", HtmlTextWriterStyle.BackgroundColor);
+ RegisterAttribute("background-image", HtmlTextWriterStyle.BackgroundImage, true, true);
+ RegisterAttribute("border-collapse", HtmlTextWriterStyle.BorderCollapse);
+ RegisterAttribute("border-color", HtmlTextWriterStyle.BorderColor);
+ RegisterAttribute("border-style", HtmlTextWriterStyle.BorderStyle);
+ RegisterAttribute("border-width", HtmlTextWriterStyle.BorderWidth);
+ RegisterAttribute("color", HtmlTextWriterStyle.Color);
+ RegisterAttribute("cursor", HtmlTextWriterStyle.Cursor);
+ RegisterAttribute("direction", HtmlTextWriterStyle.Direction);
+ RegisterAttribute("display", HtmlTextWriterStyle.Display);
+ RegisterAttribute("filter", HtmlTextWriterStyle.Filter);
+ RegisterAttribute("font-family", HtmlTextWriterStyle.FontFamily, true);
+ RegisterAttribute("font-size", HtmlTextWriterStyle.FontSize);
+ RegisterAttribute("font-style", HtmlTextWriterStyle.FontStyle);
+ RegisterAttribute("font-variant", HtmlTextWriterStyle.FontVariant);
+ RegisterAttribute("font-weight", HtmlTextWriterStyle.FontWeight);
+ RegisterAttribute("height", HtmlTextWriterStyle.Height);
+ RegisterAttribute("left", HtmlTextWriterStyle.Left);
+ RegisterAttribute("list-style-image", HtmlTextWriterStyle.ListStyleImage, true, true);
+ RegisterAttribute("list-style-type", HtmlTextWriterStyle.ListStyleType);
+ RegisterAttribute("margin", HtmlTextWriterStyle.Margin);
+ RegisterAttribute("margin-bottom", HtmlTextWriterStyle.MarginBottom);
+ RegisterAttribute("margin-left", HtmlTextWriterStyle.MarginLeft);
+ RegisterAttribute("margin-right", HtmlTextWriterStyle.MarginRight);
+ RegisterAttribute("margin-top", HtmlTextWriterStyle.MarginTop);
+ RegisterAttribute("overflow-x", HtmlTextWriterStyle.OverflowX);
+ RegisterAttribute("overflow-y", HtmlTextWriterStyle.OverflowY);
+ RegisterAttribute("overflow", HtmlTextWriterStyle.Overflow);
+ RegisterAttribute("padding", HtmlTextWriterStyle.Padding);
+ RegisterAttribute("padding-bottom", HtmlTextWriterStyle.PaddingBottom);
+ RegisterAttribute("padding-left", HtmlTextWriterStyle.PaddingLeft);
+ RegisterAttribute("padding-right", HtmlTextWriterStyle.PaddingRight);
+ RegisterAttribute("padding-top", HtmlTextWriterStyle.PaddingTop);
+ RegisterAttribute("position", HtmlTextWriterStyle.Position);
+ RegisterAttribute("text-align", HtmlTextWriterStyle.TextAlign);
+ RegisterAttribute("text-decoration", HtmlTextWriterStyle.TextDecoration);
+ RegisterAttribute("text-overflow", HtmlTextWriterStyle.TextOverflow);
+ RegisterAttribute("top", HtmlTextWriterStyle.Top);
+ RegisterAttribute("vertical-align", HtmlTextWriterStyle.VerticalAlign);
+ RegisterAttribute("visibility", HtmlTextWriterStyle.Visibility);
+ RegisterAttribute("width", HtmlTextWriterStyle.Width);
+ RegisterAttribute("white-space", HtmlTextWriterStyle.WhiteSpace);
+ RegisterAttribute("z-index", HtmlTextWriterStyle.ZIndex);
+ }
+
+ ///
+ /// Returns the HtmlTextWriterStyle value for known style attributes.
+ ///
+ public static HtmlTextWriterStyle GetStyleKey(string styleName)
+ {
+ if (!string.IsNullOrEmpty(styleName))
+ {
+ if (attrKeyLookupTable.TryGetValue(styleName, out var key))
+ {
+ return key;
+ }
+ }
+
+ return (HtmlTextWriterStyle)(-1);
+ }
+
+ ///
+ /// Returns the name of the attribute corresponding to the specified HtmlTextWriterStyle value.
+ ///
+ public static string GetStyleName(HtmlTextWriterStyle styleKey)
+ {
+ return (int)styleKey >= 0 && (int)styleKey < attrNameLookupArray.Count ? attrNameLookupArray[(int)styleKey].Name : string.Empty;
+ }
+
+ ///
+ /// Does the specified style key require attribute value encoding if the value is being
+ /// rendered in a style attribute.
+ ///
+ public static bool IsStyleEncoded(HtmlTextWriterStyle styleKey)
+ {
+ return (int)styleKey >= 0 && (int)styleKey < attrNameLookupArray.Count ? attrNameLookupArray[(int)styleKey].Encode : true;
+ }
+
+ ///
+ ///
+ /// Registers the specified style attribute to create a mapping between a string representation
+ /// and the corresponding HtmlTextWriterStyle value.
+ ///
+ internal static void RegisterAttribute(string name, HtmlTextWriterStyle key)
+ {
+ RegisterAttribute(name, key, false, false);
+ }
+
+ ///
+ ///
+ /// Registers the specified style attribute to create a mapping between a string representation
+ /// and the corresponding HtmlTextWriterStyle value.
+ ///
+ internal static void RegisterAttribute(string name, HtmlTextWriterStyle key, bool encode)
+ {
+ RegisterAttribute(name, key, encode, false);
+ }
+
+ ///
+ ///
+ /// Registers the specified style attribute to create a mapping between a string representation
+ /// and the corresponding HtmlTextWriterStyle value.
+ /// In addition, the mapping can include additional information about the attribute type
+ /// such as whether it is a URL.
+ ///
+ internal static void RegisterAttribute(string name, HtmlTextWriterStyle key, bool encode, bool isUrl)
+ {
+ attrKeyLookupTable[name] = key;
+
+ if ((int)key < attrNameLookupArray.Count)
+ {
+ attrNameLookupArray[(int)key] = new AttributeInformation(name, encode, isUrl);
+ }
+ }
+
+ ///
+ /// Render the specified style attribute into the specified TextWriter.
+ /// This method contains all the logic for rendering a CSS name/value pair.
+ ///
+ private static void WriteAttribute(TextWriter writer, HtmlTextWriterStyle key, string name, string value)
+ {
+ writer.Write(name);
+ writer.Write(':');
+
+ bool isUrl = false;
+ if (key != (HtmlTextWriterStyle)(-1))
+ {
+ isUrl = attrNameLookupArray[(int)key].IsUrl;
+ }
+
+ if (isUrl == false)
+ {
+ writer.Write(value);
+ }
+ else
+ {
+ WriteUrlAttribute(writer, value);
+ }
+
+ writer.Write(';');
+ }
+
+ ///
+ /// Render the specified style attributes. This is used by HtmlTextWriter to render out all
+ /// its collected style attributes.
+ ///
+ internal static void WriteAttributes(TextWriter writer, IEnumerable styles)
+ {
+ foreach (var style in styles)
+ {
+ WriteAttribute(writer, style.Key, style.Name, style.Value);
+ }
+ }
+
+ ///
+ /// Writes out the specified URL value with the appropriate encoding
+ /// and url() syntax.
+ /// internal for unit testing.
+ ///
+ internal static void WriteUrlAttribute(TextWriter writer, string url)
+ {
+ string urlValue = url;
+
+ char[] quotes = new char[] { '\'', '"' };
+ char? surroundingQuote = null;
+
+ if (url.StartsWith("url(", StringComparison.OrdinalIgnoreCase))
+ {
+ int urlIndex = 4;
+ int urlLength = url.Length - 4;
+ if (url.EndsWith(')'))
+ {
+ urlLength--;
+ }
+
+ // extract out the actual URL value
+ urlValue = url.Substring(urlIndex, urlLength).Trim();
+ }
+
+ // The CSS specification http://www.w3.org/TR/CSS2/syndata.html#uri says the ' and " characters are
+ // optional for specifying the url values.
+ // And we do not want to pass them to UrlPathEncode if they are present.
+ foreach (char quote in quotes)
+ {
+ if (urlValue.StartsWith(quote) && urlValue.EndsWith(quote))
+ {
+ urlValue = urlValue.Trim(quote);
+ surroundingQuote = quote;
+ break;
+ }
+ }
+
+ // write out the "url(" prefix
+ writer.Write("url(");
+ if (surroundingQuote != null)
+ {
+ writer.Write(surroundingQuote);
+ }
+
+ writer.Write(HttpUtility.UrlPathEncode(urlValue));
+
+ if (surroundingQuote != null)
+ {
+ writer.Write(surroundingQuote);
+ }
+ // write out the end of the "url()" syntax
+ writer.Write(")");
+ }
+
+ ///
+ /// Holds information about each registered style attribute.
+ ///
+ private readonly record struct AttributeInformation(string Name, bool Encode, bool IsUrl);
+}
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriter.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriter.cs
new file mode 100644
index 000000000..a64e5fc13
--- /dev/null
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriter.cs
@@ -0,0 +1,1334 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace System.Web.UI;
+
+[SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = Constants.ApiFromAspNet)]
+[SuppressMessage("Naming", "CA1721:Property names should not match get methods", Justification = Constants.ApiFromAspNet)]
+[SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = Constants.ApiFromAspNet)]
+public class HtmlTextWriter : TextWriter
+{
+ public const char TagLeftChar = '<';
+ public const char TagRightChar = '>';
+ public const string SelfClosingChars = " /";
+ public const string SelfClosingTagEnd = " />";
+ public const string EndTagLeftChars = "";
+ public const char DoubleQuoteChar = '"';
+ public const char SingleQuoteChar = '\'';
+ public const char SpaceChar = ' ';
+ public const char EqualsChar = '=';
+ public const char SlashChar = '/';
+ public const string EqualsDoubleQuoteString = "=\"";
+ public const char SemicolonChar = ';';
+ public const char StyleEqualsChar = ':';
+ public const string DefaultTabString = "\t";
+
+ // The DesignerRegion attribute name must be kept in sync with
+ // System.Web.UI.Design.DesignerRegion.DesignerRegionNameAttribute
+ internal const string DesignerRegionAttributeName = "_designerRegion";
+
+ private static readonly Dictionary _tagKeyLookupTable = new((int)HtmlTextWriterTag.Xml + 1, StringComparer.OrdinalIgnoreCase);
+ private static readonly TagInformation[] _tagNameLookupArray = new TagInformation[(int)HtmlTextWriterTag.Xml + 1];
+ private static readonly Dictionary _attrKeyLookupTable = new((int)HtmlTextWriterAttribute.VCardName + 1);
+ private static readonly AttributeInformation[] _attrNameLookupArray = new AttributeInformation[(int)HtmlTextWriterAttribute.VCardName + 1];
+
+ private int _indentLevel;
+ private bool _tabsPending;
+ private readonly bool _isDescendant;
+ private int _tagIndex;
+ private HtmlTextWriterTag _tagKey;
+ private string? _tagName;
+
+ private readonly Stack _endTags = new();
+ private readonly List _styleList = new();
+ private readonly List _attrList = new();
+ private readonly string _tabString;
+
+ static HtmlTextWriter()
+ {
+ RegisterTag(string.Empty, HtmlTextWriterTag.Unknown, TagType.Other);
+ RegisterTag("a", HtmlTextWriterTag.A, TagType.Inline);
+ RegisterTag("acronym", HtmlTextWriterTag.Acronym, TagType.Inline);
+ RegisterTag("address", HtmlTextWriterTag.Address, TagType.Other);
+ RegisterTag("area", HtmlTextWriterTag.Area, TagType.NonClosing);
+ RegisterTag("b", HtmlTextWriterTag.B, TagType.Inline);
+ RegisterTag("base", HtmlTextWriterTag.Base, TagType.NonClosing);
+ RegisterTag("basefont", HtmlTextWriterTag.Basefont, TagType.NonClosing);
+ RegisterTag("bdo", HtmlTextWriterTag.Bdo, TagType.Inline);
+ RegisterTag("bgsound", HtmlTextWriterTag.Bgsound, TagType.NonClosing);
+ RegisterTag("big", HtmlTextWriterTag.Big, TagType.Inline);
+ RegisterTag("blockquote", HtmlTextWriterTag.Blockquote, TagType.Other);
+ RegisterTag("body", HtmlTextWriterTag.Body, TagType.Other);
+ RegisterTag("br", HtmlTextWriterTag.Br, TagType.NonClosing);
+ RegisterTag("button", HtmlTextWriterTag.Button, TagType.Inline);
+ RegisterTag("caption", HtmlTextWriterTag.Caption, TagType.Other);
+ RegisterTag("center", HtmlTextWriterTag.Center, TagType.Other);
+ RegisterTag("cite", HtmlTextWriterTag.Cite, TagType.Inline);
+ RegisterTag("code", HtmlTextWriterTag.Code, TagType.Inline);
+ RegisterTag("col", HtmlTextWriterTag.Col, TagType.NonClosing);
+ RegisterTag("colgroup", HtmlTextWriterTag.Colgroup, TagType.Other);
+ RegisterTag("del", HtmlTextWriterTag.Del, TagType.Inline);
+ RegisterTag("dd", HtmlTextWriterTag.Dd, TagType.Inline);
+ RegisterTag("dfn", HtmlTextWriterTag.Dfn, TagType.Inline);
+ RegisterTag("dir", HtmlTextWriterTag.Dir, TagType.Other);
+ RegisterTag("div", HtmlTextWriterTag.Div, TagType.Other);
+ RegisterTag("dl", HtmlTextWriterTag.Dl, TagType.Other);
+ RegisterTag("dt", HtmlTextWriterTag.Dt, TagType.Inline);
+ RegisterTag("em", HtmlTextWriterTag.Em, TagType.Inline);
+ RegisterTag("embed", HtmlTextWriterTag.Embed, TagType.NonClosing);
+ RegisterTag("fieldset", HtmlTextWriterTag.Fieldset, TagType.Other);
+ RegisterTag("font", HtmlTextWriterTag.Font, TagType.Inline);
+ RegisterTag("form", HtmlTextWriterTag.Form, TagType.Other);
+ RegisterTag("frame", HtmlTextWriterTag.Frame, TagType.NonClosing);
+ RegisterTag("frameset", HtmlTextWriterTag.Frameset, TagType.Other);
+ RegisterTag("h1", HtmlTextWriterTag.H1, TagType.Other);
+ RegisterTag("h2", HtmlTextWriterTag.H2, TagType.Other);
+ RegisterTag("h3", HtmlTextWriterTag.H3, TagType.Other);
+ RegisterTag("h4", HtmlTextWriterTag.H4, TagType.Other);
+ RegisterTag("h5", HtmlTextWriterTag.H5, TagType.Other);
+ RegisterTag("h6", HtmlTextWriterTag.H6, TagType.Other);
+ RegisterTag("head", HtmlTextWriterTag.Head, TagType.Other);
+ RegisterTag("hr", HtmlTextWriterTag.Hr, TagType.NonClosing);
+ RegisterTag("html", HtmlTextWriterTag.Html, TagType.Other);
+ RegisterTag("i", HtmlTextWriterTag.I, TagType.Inline);
+ RegisterTag("iframe", HtmlTextWriterTag.Iframe, TagType.Other);
+ RegisterTag("img", HtmlTextWriterTag.Img, TagType.NonClosing);
+ RegisterTag("input", HtmlTextWriterTag.Input, TagType.NonClosing);
+ RegisterTag("ins", HtmlTextWriterTag.Ins, TagType.Inline);
+ RegisterTag("isindex", HtmlTextWriterTag.Isindex, TagType.NonClosing);
+ RegisterTag("kbd", HtmlTextWriterTag.Kbd, TagType.Inline);
+ RegisterTag("label", HtmlTextWriterTag.Label, TagType.Inline);
+ RegisterTag("legend", HtmlTextWriterTag.Legend, TagType.Other);
+ RegisterTag("li", HtmlTextWriterTag.Li, TagType.Inline);
+ RegisterTag("link", HtmlTextWriterTag.Link, TagType.NonClosing);
+ RegisterTag("map", HtmlTextWriterTag.Map, TagType.Other);
+ RegisterTag("marquee", HtmlTextWriterTag.Marquee, TagType.Other);
+ RegisterTag("menu", HtmlTextWriterTag.Menu, TagType.Other);
+ RegisterTag("meta", HtmlTextWriterTag.Meta, TagType.NonClosing);
+ RegisterTag("nobr", HtmlTextWriterTag.Nobr, TagType.Inline);
+ RegisterTag("noframes", HtmlTextWriterTag.Noframes, TagType.Other);
+ RegisterTag("noscript", HtmlTextWriterTag.Noscript, TagType.Other);
+ RegisterTag("object", HtmlTextWriterTag.Object, TagType.Other);
+ RegisterTag("ol", HtmlTextWriterTag.Ol, TagType.Other);
+ RegisterTag("option", HtmlTextWriterTag.Option, TagType.Other);
+ RegisterTag("p", HtmlTextWriterTag.P, TagType.Inline);
+ RegisterTag("param", HtmlTextWriterTag.Param, TagType.Other);
+ RegisterTag("pre", HtmlTextWriterTag.Pre, TagType.Other);
+ RegisterTag("ruby", HtmlTextWriterTag.Ruby, TagType.Other);
+ RegisterTag("rt", HtmlTextWriterTag.Rt, TagType.Other);
+ RegisterTag("q", HtmlTextWriterTag.Q, TagType.Inline);
+ RegisterTag("s", HtmlTextWriterTag.S, TagType.Inline);
+ RegisterTag("samp", HtmlTextWriterTag.Samp, TagType.Inline);
+ RegisterTag("script", HtmlTextWriterTag.Script, TagType.Other);
+ RegisterTag("select", HtmlTextWriterTag.Select, TagType.Other);
+ RegisterTag("small", HtmlTextWriterTag.Small, TagType.Other);
+ RegisterTag("span", HtmlTextWriterTag.Span, TagType.Inline);
+ RegisterTag("strike", HtmlTextWriterTag.Strike, TagType.Inline);
+ RegisterTag("strong", HtmlTextWriterTag.Strong, TagType.Inline);
+ RegisterTag("style", HtmlTextWriterTag.Style, TagType.Other);
+ RegisterTag("sub", HtmlTextWriterTag.Sub, TagType.Inline);
+ RegisterTag("sup", HtmlTextWriterTag.Sup, TagType.Inline);
+ RegisterTag("table", HtmlTextWriterTag.Table, TagType.Other);
+ RegisterTag("tbody", HtmlTextWriterTag.Tbody, TagType.Other);
+ RegisterTag("td", HtmlTextWriterTag.Td, TagType.Inline);
+ RegisterTag("textarea", HtmlTextWriterTag.Textarea, TagType.Inline);
+ RegisterTag("tfoot", HtmlTextWriterTag.Tfoot, TagType.Other);
+ RegisterTag("th", HtmlTextWriterTag.Th, TagType.Inline);
+ RegisterTag("thead", HtmlTextWriterTag.Thead, TagType.Other);
+ RegisterTag("title", HtmlTextWriterTag.Title, TagType.Other);
+ RegisterTag("tr", HtmlTextWriterTag.Tr, TagType.Other);
+ RegisterTag("tt", HtmlTextWriterTag.Tt, TagType.Inline);
+ RegisterTag("u", HtmlTextWriterTag.U, TagType.Inline);
+ RegisterTag("ul", HtmlTextWriterTag.Ul, TagType.Other);
+ RegisterTag("var", HtmlTextWriterTag.Var, TagType.Inline);
+ RegisterTag("wbr", HtmlTextWriterTag.Wbr, TagType.NonClosing);
+ RegisterTag("xml", HtmlTextWriterTag.Xml, TagType.Other);
+
+ RegisterAttribute("abbr", HtmlTextWriterAttribute.Abbr, true);
+ RegisterAttribute("accesskey", HtmlTextWriterAttribute.Accesskey, true);
+ RegisterAttribute("align", HtmlTextWriterAttribute.Align, false);
+ RegisterAttribute("alt", HtmlTextWriterAttribute.Alt, true);
+ RegisterAttribute("autocomplete", HtmlTextWriterAttribute.AutoComplete, false);
+ RegisterAttribute("axis", HtmlTextWriterAttribute.Axis, true);
+ RegisterAttribute("background", HtmlTextWriterAttribute.Background, true, true);
+ RegisterAttribute("bgcolor", HtmlTextWriterAttribute.Bgcolor, false);
+ RegisterAttribute("border", HtmlTextWriterAttribute.Border, false);
+ RegisterAttribute("bordercolor", HtmlTextWriterAttribute.Bordercolor, false);
+ RegisterAttribute("cellpadding", HtmlTextWriterAttribute.Cellpadding, false);
+ RegisterAttribute("cellspacing", HtmlTextWriterAttribute.Cellspacing, false);
+ RegisterAttribute("checked", HtmlTextWriterAttribute.Checked, false);
+ RegisterAttribute("class", HtmlTextWriterAttribute.Class, true);
+ RegisterAttribute("cols", HtmlTextWriterAttribute.Cols, false);
+ RegisterAttribute("colspan", HtmlTextWriterAttribute.Colspan, false);
+ RegisterAttribute("content", HtmlTextWriterAttribute.Content, true);
+ RegisterAttribute("coords", HtmlTextWriterAttribute.Coords, false);
+ RegisterAttribute("dir", HtmlTextWriterAttribute.Dir, false);
+ RegisterAttribute("disabled", HtmlTextWriterAttribute.Disabled, false);
+ RegisterAttribute("for", HtmlTextWriterAttribute.For, false);
+ RegisterAttribute("headers", HtmlTextWriterAttribute.Headers, true);
+ RegisterAttribute("height", HtmlTextWriterAttribute.Height, false);
+ RegisterAttribute("href", HtmlTextWriterAttribute.Href, true, true);
+ RegisterAttribute("id", HtmlTextWriterAttribute.Id, false);
+ RegisterAttribute("longdesc", HtmlTextWriterAttribute.Longdesc, true, true);
+ RegisterAttribute("maxlength", HtmlTextWriterAttribute.Maxlength, false);
+ RegisterAttribute("multiple", HtmlTextWriterAttribute.Multiple, false);
+ RegisterAttribute("name", HtmlTextWriterAttribute.Name, false);
+ RegisterAttribute("nowrap", HtmlTextWriterAttribute.Nowrap, false);
+ RegisterAttribute("onclick", HtmlTextWriterAttribute.Onclick, true);
+ RegisterAttribute("onchange", HtmlTextWriterAttribute.Onchange, true);
+ RegisterAttribute("readonly", HtmlTextWriterAttribute.ReadOnly, false);
+ RegisterAttribute("rel", HtmlTextWriterAttribute.Rel, false);
+ RegisterAttribute("rows", HtmlTextWriterAttribute.Rows, false);
+ RegisterAttribute("rowspan", HtmlTextWriterAttribute.Rowspan, false);
+ RegisterAttribute("rules", HtmlTextWriterAttribute.Rules, false);
+ RegisterAttribute("scope", HtmlTextWriterAttribute.Scope, false);
+ RegisterAttribute("selected", HtmlTextWriterAttribute.Selected, false);
+ RegisterAttribute("shape", HtmlTextWriterAttribute.Shape, false);
+ RegisterAttribute("size", HtmlTextWriterAttribute.Size, false);
+ RegisterAttribute("src", HtmlTextWriterAttribute.Src, true, true);
+ RegisterAttribute("style", HtmlTextWriterAttribute.Style, false);
+ RegisterAttribute("tabindex", HtmlTextWriterAttribute.Tabindex, false);
+ RegisterAttribute("target", HtmlTextWriterAttribute.Target, false);
+ RegisterAttribute("title", HtmlTextWriterAttribute.Title, true);
+ RegisterAttribute("type", HtmlTextWriterAttribute.Type, false);
+ RegisterAttribute("usemap", HtmlTextWriterAttribute.Usemap, false);
+ RegisterAttribute("valign", HtmlTextWriterAttribute.Valign, false);
+ RegisterAttribute("value", HtmlTextWriterAttribute.Value, true);
+ RegisterAttribute("vcard_name", HtmlTextWriterAttribute.VCardName, false);
+ RegisterAttribute("width", HtmlTextWriterAttribute.Width, false);
+ RegisterAttribute("wrap", HtmlTextWriterAttribute.Wrap, false);
+ RegisterAttribute(DesignerRegionAttributeName, HtmlTextWriterAttribute.DesignerRegion, false);
+ }
+
+ public virtual bool IsValidFormAttribute(string attribute)
+ {
+ return true;
+ }
+
+ public override Encoding Encoding => InnerWriter.Encoding;
+
+ [AllowNull]
+ public override string NewLine
+ {
+ get
+ {
+ return InnerWriter.NewLine;
+ }
+
+ set
+ {
+ InnerWriter.NewLine = value;
+ }
+ }
+
+ public int Indent
+ {
+ get
+ {
+ return _indentLevel;
+ }
+ set
+ {
+ Debug.Assert(value >= 0, "Bogus Indent... probably caused by mismatched Indent++ and Indent--");
+ if (value < 0)
+ {
+ value = 0;
+ }
+ _indentLevel = value;
+ }
+ }
+
+ //Gets or sets the TextWriter to use.
+ public TextWriter InnerWriter { get; set; }
+
+ public virtual void BeginRender()
+ {
+ }
+
+ //Closes the document being written to.
+ public override void Close()
+ {
+ InnerWriter.Close();
+ }
+
+ public virtual void EndRender()
+ {
+ }
+
+ public override void Flush()
+ {
+ InnerWriter.Flush();
+ }
+
+ protected virtual void OutputTabs()
+ {
+ if (_tabsPending)
+ {
+ for (var i = 0; i < _indentLevel; i++)
+ {
+ InnerWriter.Write(_tabString);
+ }
+ _tabsPending = false;
+ }
+ }
+
+ public override void Write(string? value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(bool value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(char value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(char[]? buffer)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(buffer);
+ }
+
+ public override void Write(char[] buffer, int index, int count)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(buffer, index, count);
+ }
+
+ public override void Write(double value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(float value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(int value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(long value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(object? value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(value);
+ }
+
+ public override void Write(string format, object? arg0)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(format, arg0);
+ }
+
+ public override void Write(string format, object? arg0, object? arg1)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(format, arg0, arg1);
+ }
+
+ public override void Write(string format, params object?[] arg)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(format, arg);
+ }
+
+ public void WriteLineNoTabs(string s)
+ {
+ InnerWriter.WriteLine(s);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(string? value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine()
+ {
+ InnerWriter.WriteLine();
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(bool value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(char value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(char[]? buffer)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(buffer);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(char[] buffer, int index, int count)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(buffer, index, count);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(double value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(float value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(int value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(long value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(object? value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(string format, object? arg0)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(format, arg0);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(string format, object? arg0, object? arg1)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(format, arg0, arg1);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(string format, params object?[] arg)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(format, arg);
+ _tabsPending = true;
+ }
+
+ public override void WriteLine(uint value)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.WriteLine(value);
+ _tabsPending = true;
+ }
+
+ protected static void RegisterTag(string name, HtmlTextWriterTag key)
+ {
+ ArgumentNullException.ThrowIfNull(name);
+
+ RegisterTag(name, key, TagType.Other);
+ }
+
+ [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Tags should be lower case")]
+ private static void RegisterTag(string name, HtmlTextWriterTag key, TagType type)
+ {
+ _tagKeyLookupTable[name] = key;
+
+ // Pre-resolve the end tag
+ string? endTag = null;
+ if (type != TagType.NonClosing && key != HtmlTextWriterTag.Unknown)
+ {
+ endTag = EndTagLeftChars + name.ToLowerInvariant() + TagRightChar.ToString(CultureInfo.InvariantCulture);
+ }
+
+ if ((int)key < _tagNameLookupArray.Length)
+ {
+ _tagNameLookupArray[(int)key] = new TagInformation(name, type, endTag);
+ }
+ }
+
+ protected static void RegisterAttribute(string name, HtmlTextWriterAttribute key)
+ {
+ RegisterAttribute(name, key, false);
+ }
+
+ private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool encode)
+ {
+ RegisterAttribute(name, key, encode, false);
+ }
+
+ private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool encode, bool isUrl)
+ {
+ _attrKeyLookupTable[name] = key;
+
+ if ((int)key < _attrNameLookupArray.Length)
+ {
+ _attrNameLookupArray[(int)key] = new AttributeInformation(name, encode, isUrl);
+ }
+ }
+
+ protected static void RegisterStyle(string name, HtmlTextWriterStyle key)
+ {
+ CssTextWriter.RegisterAttribute(name, key);
+ }
+
+ public HtmlTextWriter(TextWriter writer) : this(writer, DefaultTabString)
+ {
+ }
+
+ public HtmlTextWriter(TextWriter writer, string tabString)
+ : base(CultureInfo.InvariantCulture)
+ {
+ InnerWriter = writer;
+
+ _tabString = tabString;
+ _indentLevel = 0;
+ _tabsPending = false;
+ _isDescendant = GetType() != typeof(HtmlTextWriter);
+ }
+
+ protected HtmlTextWriterTag TagKey
+ {
+ get
+ {
+ return _tagKey;
+ }
+ set
+ {
+ _tagIndex = (int)value;
+ if (_tagIndex < 0 || _tagIndex >= _tagNameLookupArray.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value));
+ }
+ _tagKey = value;
+
+ // If explicitly setting to unknown, keep the old tag name. This allows a string tag
+ // to be set without clobbering it if setting TagKey to itself.
+ if (value != HtmlTextWriterTag.Unknown)
+ {
+ _tagName = _tagNameLookupArray[_tagIndex].Name;
+ }
+ }
+ }
+
+ protected string? TagName
+ {
+ get
+ {
+ return _tagName;
+ }
+ set
+ {
+ _tagName = value;
+ _tagKey = GetTagKey(_tagName);
+ _tagIndex = (int)_tagKey;
+ Debug.Assert(_tagIndex >= 0 && _tagIndex < _tagNameLookupArray.Length);
+ }
+ }
+
+ public virtual void AddAttribute(string name, string value)
+ {
+ var attributeKey = GetAttributeKey(name);
+ value = EncodeAttributeValue(attributeKey, value);
+
+ AddAttribute(name, value, attributeKey);
+ }
+
+ //do not fix this spelling error
+ //believe it or not, it is a backwards breaking change for languages that
+ //support late binding with named parameters VB.Net
+ public virtual void AddAttribute(string name, string value, bool fEndode)
+ {
+ value = EncodeAttributeValue(value, fEndode);
+ AddAttribute(name, value, GetAttributeKey(name));
+ }
+
+ public virtual void AddAttribute(HtmlTextWriterAttribute key, string value)
+ {
+ var attributeIndex = (int)key;
+ if (attributeIndex >= 0 && attributeIndex < _attrNameLookupArray.Length)
+ {
+ var info = _attrNameLookupArray[attributeIndex];
+ AddAttribute(info.Name, value, key, info.Encode, info.IsUrl);
+ }
+ }
+
+ public virtual void AddAttribute(HtmlTextWriterAttribute key, string value, bool fEncode)
+ {
+ var attributeIndex = (int)key;
+ if (attributeIndex >= 0 && attributeIndex < _attrNameLookupArray.Length)
+ {
+ var info = _attrNameLookupArray[attributeIndex];
+ AddAttribute(info.Name, value, key, fEncode, info.IsUrl);
+ }
+ }
+
+ protected virtual void AddAttribute(string name, string value, HtmlTextWriterAttribute key)
+ {
+ AddAttribute(name, value, key, false, false);
+ }
+
+ private void AddAttribute(string name, string value, HtmlTextWriterAttribute key, bool encode, bool isUrl)
+ {
+ _attrList.Add(new RenderAttribute(name, value, key, encode, isUrl));
+ }
+
+ public virtual void AddStyleAttribute(string name, string value)
+ {
+ AddStyleAttribute(name, value, CssTextWriter.GetStyleKey(name));
+ }
+
+ public virtual void AddStyleAttribute(HtmlTextWriterStyle key, string value)
+ {
+ AddStyleAttribute(CssTextWriter.GetStyleName(key), value, key);
+ }
+
+ protected virtual void AddStyleAttribute(string name, string value, HtmlTextWriterStyle key)
+ {
+ var style = new RenderStyle(name, value, key);
+
+ if (CssTextWriter.IsStyleEncoded(key))
+ {
+ // note that only css attributes in an inline style value need to be attribute encoded
+ // since CssTextWriter is used to render both embedded stylesheets and style attributes
+ // the attribute encoding is done here.
+ style = style with { Value = HttpUtility.HtmlAttributeEncode(value) };
+ }
+
+ _styleList.Add(style);
+ }
+
+ [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = Constants.ApiFromAspNet)]
+ [return: NotNullIfNotNull(nameof(value))]
+ protected string? EncodeAttributeValue(string value, bool fEncode)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+
+ return !fEncode ? value : HttpUtility.HtmlAttributeEncode(value);
+ }
+
+ [return: NotNullIfNotNull(nameof(value))]
+ protected virtual string? EncodeAttributeValue(HtmlTextWriterAttribute attrKey, string value)
+ {
+ var encode = true;
+
+ if (0 <= (int)attrKey && (int)attrKey < _attrNameLookupArray.Length)
+ {
+ encode = _attrNameLookupArray[(int)attrKey].Encode;
+ }
+
+ return EncodeAttributeValue(value, encode);
+ }
+
+ // This does minimal URL encoding by converting spaces in the url to "%20".
+ [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = Constants.ApiFromAspNet)]
+ protected string EncodeUrl(string url)
+ {
+ ArgumentNullException.ThrowIfNull(url);
+
+ // VSWhidbey 454348: escaped spaces in UNC share paths don't work in IE, so
+ // we're not going to encode if it's a share.
+ return !IsUncSharePath(url) ? HttpUtility.UrlPathEncode(url) : url;
+
+ static bool IsUncSharePath(string path)
+ {
+ // e.g \\server\share\foo or //server/share/foo
+ return path.Length > 2 && IsDirectorySeparatorChar(path[0]) && IsDirectorySeparatorChar(path[1]);
+ }
+
+ static bool IsDirectorySeparatorChar(char ch)
+ {
+ return (ch == '\\' || ch == '/');
+ }
+ }
+
+ [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = Constants.ApiFromAspNet)]
+ protected HtmlTextWriterAttribute GetAttributeKey(string attrName)
+ {
+ if (!string.IsNullOrEmpty(attrName))
+ {
+ if (_attrKeyLookupTable.TryGetValue(attrName, out var key))
+ {
+ return key;
+ }
+ }
+
+ return (HtmlTextWriterAttribute)(-1);
+ }
+
+ [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = Constants.ApiFromAspNet)]
+ protected string GetAttributeName(HtmlTextWriterAttribute attrKey)
+ {
+ return (int)attrKey >= 0 && (int)attrKey < _attrNameLookupArray.Length ? _attrNameLookupArray[(int)attrKey].Name : string.Empty;
+ }
+
+ [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = Constants.ApiFromAspNet)]
+ protected HtmlTextWriterStyle GetStyleKey(string styleName)
+ {
+ return CssTextWriter.GetStyleKey(styleName);
+ }
+
+ [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = Constants.ApiFromAspNet)]
+ protected string GetStyleName(HtmlTextWriterStyle styleKey)
+ {
+ return CssTextWriter.GetStyleName(styleKey);
+ }
+
+ protected virtual HtmlTextWriterTag GetTagKey(string? tagName)
+ {
+ if (!string.IsNullOrEmpty(tagName))
+ {
+ if (_tagKeyLookupTable.TryGetValue(tagName, out var key))
+ {
+ return key;
+ }
+ }
+
+ return HtmlTextWriterTag.Unknown;
+ }
+
+ protected virtual string GetTagName(HtmlTextWriterTag tagKey)
+ {
+ var tagIndex = (int)tagKey;
+ return tagIndex >= 0 && tagIndex < _tagNameLookupArray.Length ? _tagNameLookupArray[tagIndex].Name : string.Empty;
+ }
+
+ protected bool IsAttributeDefined(HtmlTextWriterAttribute key)
+ {
+ foreach (var attr in _attrList)
+ {
+ if (attr.Key == key)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected bool IsAttributeDefined(HtmlTextWriterAttribute key, [MaybeNullWhen(false)] out string value)
+ {
+ value = null;
+ foreach (var attr in _attrList)
+ {
+ if (attr.Key == key)
+ {
+ value = attr.Value;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key)
+ {
+ foreach (var style in _styleList)
+ {
+ if (style.Key == key)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key, [MaybeNullWhen(false)] out string value)
+ {
+ value = null;
+ foreach (var style in _styleList)
+ {
+ if (style.Key == key)
+ {
+ value = style.Value;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected virtual bool OnAttributeRender(string name, string? value, HtmlTextWriterAttribute key)
+ {
+ return true;
+ }
+
+ protected virtual bool OnStyleAttributeRender(string name, string? value, HtmlTextWriterStyle key)
+ {
+ return true;
+ }
+
+ protected virtual bool OnTagRender(string? name, HtmlTextWriterTag key)
+ {
+ return true;
+ }
+
+ protected string? PopEndTag()
+ {
+ if (_endTags.Count == 0)
+ {
+ throw new InvalidOperationException("A PopEndTag was called without a corresponding PushEndTag.");
+ }
+
+ var endTag = _endTags.Pop();
+
+ TagKey = endTag.Tag;
+
+ return endTag.Text;
+ }
+
+ protected void PushEndTag(string? endTag)
+ {
+ _endTags.Push(new TagStackEntry(_tagKey, endTag));
+ }
+
+ protected virtual void FilterAttributes()
+ {
+ _styleList.RemoveAll(style => !OnStyleAttributeRender(style.Name, style.Value, style.Key));
+ _attrList.RemoveAll(attr => !OnAttributeRender(attr.Name, attr.Value, attr.Key));
+ }
+
+ public virtual void RenderBeginTag(string tagName)
+ {
+ TagName = tagName;
+ RenderBeginTag(_tagKey);
+ }
+
+ public virtual void RenderBeginTag(HtmlTextWriterTag tagKey)
+ {
+ TagKey = tagKey;
+ var renderTag = true;
+
+ if (_isDescendant)
+ {
+ renderTag = OnTagRender(_tagName, _tagKey);
+
+ // Inherited renderers will be expecting to be able to filter any of the attributes at this point
+ FilterAttributes();
+
+ // write text before begin tag
+ var textBeforeTag = RenderBeforeTag();
+ if (textBeforeTag != null)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(textBeforeTag);
+ }
+ }
+
+ // gather information about this tag.
+ var tagInfo = _tagNameLookupArray[_tagIndex];
+ var tagType = tagInfo.TagType;
+ var renderEndTag = renderTag && (tagType != TagType.NonClosing);
+ var endTag = renderEndTag ? tagInfo.ClosingTag : null;
+
+ // write the begin tag
+ if (renderTag)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(TagLeftChar);
+ InnerWriter.Write(_tagName);
+
+ string? styleValue = null;
+
+ foreach (var attr in _attrList)
+ {
+ if (attr.Key == HtmlTextWriterAttribute.Style)
+ {
+ // append style attribute in with other styles
+ styleValue = attr.Value;
+ }
+ else
+ {
+ InnerWriter.Write(SpaceChar);
+ InnerWriter.Write(attr.Name);
+ if (attr.Value != null)
+ {
+ InnerWriter.Write(EqualsDoubleQuoteString);
+
+ var attrValue = attr.Value;
+ if (attr.IsUrl)
+ {
+ if (attr.Key != HtmlTextWriterAttribute.Href || !attrValue.StartsWith("javascript:", StringComparison.Ordinal))
+ {
+ attrValue = EncodeUrl(attrValue);
+ }
+ }
+ if (attr.Encode)
+ {
+ WriteHtmlAttributeEncode(attrValue);
+ }
+ else
+ {
+ InnerWriter.Write(attrValue);
+ }
+ InnerWriter.Write(DoubleQuoteChar);
+ }
+ }
+ }
+
+ if (_styleList.Count > 0 || styleValue != null)
+ {
+ InnerWriter.Write(SpaceChar);
+ InnerWriter.Write("style");
+ InnerWriter.Write(EqualsDoubleQuoteString);
+
+ CssTextWriter.WriteAttributes(InnerWriter, _styleList);
+ if (styleValue != null)
+ {
+ InnerWriter.Write(styleValue);
+ }
+ InnerWriter.Write(DoubleQuoteChar);
+ }
+
+ if (tagType == TagType.NonClosing)
+ {
+ InnerWriter.Write(SelfClosingTagEnd);
+ }
+ else
+ {
+ InnerWriter.Write(TagRightChar);
+ }
+ }
+
+ var textBeforeContent = RenderBeforeContent();
+ if (textBeforeContent != null)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(textBeforeContent);
+ }
+
+ // write text before the content
+ if (renderEndTag)
+ {
+ if (tagType != TagType.Inline)
+ {
+ WriteLine();
+ Indent++;
+ }
+
+ // Manually build end tags for unknown tag types.
+ if (endTag == null)
+ {
+ endTag = EndTagLeftChars + _tagName + TagRightChar.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+
+ if (_isDescendant)
+ {
+ // append text after the tag
+ var textAfterTag = RenderAfterTag();
+ if (textAfterTag != null)
+ {
+ endTag = (endTag == null) ? textAfterTag : textAfterTag + endTag;
+ }
+
+ // build end content and push it on stack to write in RenderEndTag
+ // prepend text after the content
+ var textAfterContent = RenderAfterContent();
+ if (textAfterContent != null)
+ {
+ endTag = (endTag == null) ? textAfterContent : textAfterContent + endTag;
+ }
+ }
+
+ // push end tag onto stack
+ PushEndTag(endTag);
+
+ // flush attribute and style lists for next tag
+ _attrList.Clear();
+ _styleList.Clear();
+ }
+
+ public virtual void RenderEndTag()
+ {
+ var endTag = PopEndTag();
+
+ if (endTag != null)
+ {
+ if (_tagNameLookupArray[_tagIndex].TagType == TagType.Inline)
+ {
+ // Never inject crlfs at end of inline tags.
+ //
+ Write(endTag);
+ }
+ else
+ {
+ // unindent if not an inline tag
+ WriteLine();
+ Indent--;
+ Write(endTag);
+ }
+ }
+ }
+
+ protected virtual string? RenderBeforeTag()
+ {
+ return null;
+ }
+
+ protected virtual string? RenderBeforeContent()
+ {
+ return null;
+ }
+
+ protected virtual string? RenderAfterContent()
+ {
+ return null;
+ }
+
+ protected virtual string? RenderAfterTag()
+ {
+ return null;
+ }
+
+ public virtual void WriteAttribute(string name, string value)
+ {
+ WriteAttribute(name, value, false /*encode*/);
+ }
+
+ public virtual void WriteAttribute(string name, string value, bool fEncode)
+ {
+ InnerWriter.Write(SpaceChar);
+ InnerWriter.Write(name);
+ if (value != null)
+ {
+ InnerWriter.Write(EqualsDoubleQuoteString);
+ if (fEncode)
+ {
+ WriteHtmlAttributeEncode(value);
+ }
+ else
+ {
+ InnerWriter.Write(value);
+ }
+ InnerWriter.Write(DoubleQuoteChar);
+ }
+ }
+
+ public virtual void WriteBeginTag(string tagName)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(TagLeftChar);
+ InnerWriter.Write(tagName);
+ }
+
+ public virtual void WriteBreak()
+ {
+ // Space between br and / is for improved html compatibility. See XHTML 1.0 specification, section C.2.
+ Write("
");
+ }
+
+ public virtual void WriteFullBeginTag(string tagName)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(TagLeftChar);
+ InnerWriter.Write(tagName);
+ InnerWriter.Write(TagRightChar);
+ }
+
+ public virtual void WriteEndTag(string tagName)
+ {
+ if (_tabsPending)
+ {
+ OutputTabs();
+ }
+ InnerWriter.Write(TagLeftChar);
+ InnerWriter.Write(SlashChar);
+ InnerWriter.Write(tagName);
+ InnerWriter.Write(TagRightChar);
+ }
+
+ public virtual void WriteStyleAttribute(string name, string value)
+ {
+ WriteStyleAttribute(name, value, false /*encode*/);
+ }
+
+ public virtual void WriteStyleAttribute(string name, string value, bool fEncode)
+ {
+ InnerWriter.Write(name);
+ InnerWriter.Write(StyleEqualsChar);
+ if (fEncode)
+ {
+ WriteHtmlAttributeEncode(value);
+ }
+ else
+ {
+ InnerWriter.Write(value);
+ }
+ InnerWriter.Write(SemicolonChar);
+ }
+
+ public virtual void WriteEncodedUrl(string url)
+ {
+ ArgumentNullException.ThrowIfNull(url);
+
+ var i = url.IndexOf('?', StringComparison.OrdinalIgnoreCase);
+ if (i != -1)
+ {
+ WriteUrlEncodedString(url.Substring(0, i), false);
+ Write(url.AsSpan(i));
+ }
+ else
+ {
+ WriteUrlEncodedString(url, false);
+ }
+ }
+
+ public virtual void WriteEncodedUrlParameter(string urlText)
+ {
+ WriteUrlEncodedString(urlText, true);
+ }
+
+ public virtual void WriteEncodedText(string text)
+ {
+ ArgumentNullException.ThrowIfNull(text);
+
+ const char NBSP = '\u00A0';
+
+ // When inner text is retrieved for a text control, is
+ // decoded to 0x00A0 (code point for nbsp in Unicode).
+ // HtmlEncode doesn't encode 0x00A0 to , we need to do it
+ // manually here.
+ var length = text.Length;
+ var pos = 0;
+ while (pos < length)
+ {
+ var nbsp = text.IndexOf(NBSP, pos);
+ if (nbsp < 0)
+ {
+ HttpUtility.HtmlEncode(pos == 0 ? text : text.Substring(pos, length - pos), this);
+ pos = length;
+ }
+ else
+ {
+ if (nbsp > pos)
+ {
+ HttpUtility.HtmlEncode(text.Substring(pos, nbsp - pos), this);
+ }
+ Write(" ");
+ pos = nbsp + 1;
+ }
+ }
+ }
+
+ protected void WriteUrlEncodedString(string text, bool argument)
+ {
+ ArgumentNullException.ThrowIfNull(text);
+
+ var length = text.Length;
+ for (var i = 0; i < length; i++)
+ {
+ var ch = text[i];
+ if (IsUrlSafeChar(ch))
+ {
+ Write(ch);
+ }
+ else if (!argument &&
+ (ch == '/' ||
+ ch == ':' ||
+ ch == '#' ||
+ ch == ','
+ )
+ )
+ {
+ Write(ch);
+ }
+ else if (ch == ' ' && argument)
+ {
+ Write('+');
+ }
+ // for chars that their code number is less than 128 and have
+ // not been handled above
+ else if ((ch & 0xff80) == 0)
+ {
+ Write('%');
+ Write(IntToHex((ch >> 4) & 0xf));
+ Write(IntToHex((ch) & 0xf));
+ }
+ else
+ {
+ // VSWhidbey 448625: For DBCS characters, use UTF8 encoding
+ // which can be handled by IIS5 and above.
+ Write(HttpUtility.UrlEncode(char.ToString(ch), Encoding.UTF8));
+ }
+ }
+
+ // Set of safe chars, from RFC 1738.4 minus '+'
+ static bool IsUrlSafeChar(char ch) => ch switch
+ {
+ >= 'a' and <= 'z' => true,
+ >= 'A' and <= 'Z' => true,
+ >= '0' and <= '9' => true,
+ '-' or '_' or '.' or '!' or '*' or '(' or ')' => true,
+ _ => false,
+ };
+ }
+
+ internal void WriteHtmlAttributeEncode(string s)
+ {
+ HttpUtility.HtmlAttributeEncode(s, InnerWriter);
+ }
+
+ private static char IntToHex(int n)
+ {
+ Debug.Assert(n < 0x10);
+
+ return n <= 9 ? (char)(n + '0') : (char)(n - 10 + 'a');
+ }
+
+ private readonly record struct TagStackEntry(HtmlTextWriterTag Tag, string? Text);
+
+ private readonly record struct RenderAttribute(string Name, string Value, HtmlTextWriterAttribute Key, bool Encode, bool IsUrl);
+
+ private readonly record struct AttributeInformation(string Name, bool Encode, bool IsUrl);
+
+ private readonly record struct TagInformation(string Name, TagType TagType, string? ClosingTag);
+
+ private enum TagType
+ {
+ Inline,
+ NonClosing,
+ Other,
+ }
+}
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterAttribute.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterAttribute.cs
new file mode 100644
index 000000000..41afefedd
--- /dev/null
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterAttribute.cs
@@ -0,0 +1,63 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Web.UI;
+
+[Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = Constants.ApiFromAspNet)]
+public enum HtmlTextWriterAttribute
+{
+ Accesskey,
+ Align,
+ Alt,
+ Background,
+ Bgcolor,
+ Border,
+ Bordercolor,
+ Cellpadding,
+ Cellspacing,
+ Checked,
+ Class,
+ Cols,
+ Colspan,
+ Disabled,
+ For,
+ Height,
+ Href,
+ Id,
+ Maxlength,
+ Multiple,
+ Name,
+ Nowrap,
+ Onchange,
+ Onclick,
+ ReadOnly,
+ Rows,
+ Rowspan,
+ Rules,
+ Selected,
+ Size,
+ Src,
+ Style,
+ Tabindex,
+ Target,
+ Title,
+ Type,
+ Valign,
+ Value,
+ Width,
+ Wrap,
+ Abbr,
+ AutoComplete,
+ Axis,
+ Content,
+ Coords,
+ DesignerRegion,
+ Dir,
+ Headers,
+ Longdesc,
+ Rel,
+ Scope,
+ Shape,
+ Usemap,
+ VCardName,
+}
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterStyle.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterStyle.cs
new file mode 100644
index 000000000..74e2d105e
--- /dev/null
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterStyle.cs
@@ -0,0 +1,51 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Web.UI;
+
+public enum HtmlTextWriterStyle
+{
+ BackgroundColor,
+ BackgroundImage,
+ BorderCollapse,
+ BorderColor,
+ BorderStyle,
+ BorderWidth,
+ Color,
+ FontFamily,
+ FontSize,
+ FontStyle,
+ FontWeight,
+ Height,
+ TextDecoration,
+ Width,
+ ListStyleImage,
+ ListStyleType,
+ Cursor,
+ Direction,
+ Display,
+ Filter,
+ FontVariant,
+ Left,
+ Margin,
+ MarginBottom,
+ MarginLeft,
+ MarginRight,
+ MarginTop,
+ Overflow,
+ OverflowX,
+ OverflowY,
+ Padding,
+ PaddingBottom,
+ PaddingLeft,
+ PaddingRight,
+ PaddingTop,
+ Position,
+ TextAlign,
+ VerticalAlign,
+ TextOverflow,
+ Top,
+ Visibility,
+ WhiteSpace,
+ ZIndex
+}
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterTag.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterTag.cs
new file mode 100644
index 000000000..bc0cd59da
--- /dev/null
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/HtmlTextWriterTag.cs
@@ -0,0 +1,106 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Web.UI;
+
+[Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1720:Identifier contains type name", Justification = Constants.ApiFromAspNet)]
+public enum HtmlTextWriterTag
+{
+ Unknown,
+ A,
+ Acronym,
+ Address,
+ Area,
+ B,
+ Base,
+ Basefont,
+ Bdo,
+ Bgsound,
+ Big,
+ Blockquote,
+ Body,
+ Br,
+ Button,
+ Caption,
+ Center,
+ Cite,
+ Code,
+ Col,
+ Colgroup,
+ Dd,
+ Del,
+ Dfn,
+ Dir,
+ Div,
+ Dl,
+ Dt,
+ Em,
+ Embed,
+ Fieldset,
+ Font,
+ Form,
+ Frame,
+ Frameset,
+ H1,
+ H2,
+ H3,
+ H4,
+ H5,
+ H6,
+ Head,
+ Hr,
+ Html,
+ I,
+ Iframe,
+ Img,
+ Input,
+ Ins,
+ Isindex,
+ Kbd,
+ Label,
+ Legend,
+ Li,
+ Link,
+ Map,
+ Marquee,
+ Menu,
+ Meta,
+ Nobr,
+ Noframes,
+ Noscript,
+ Object,
+ Ol,
+ Option,
+ P,
+ Param,
+ Pre,
+ Q,
+ Rt,
+ Ruby,
+ S,
+ Samp,
+ Script,
+ Select,
+ Small,
+ Span,
+ Strike,
+ Strong,
+ Style,
+ Sub,
+ Sup,
+ Table,
+ Tbody,
+ Td,
+ Textarea,
+ Tfoot,
+ Th,
+ Thead,
+ Title,
+ Tr,
+ Tt,
+ U,
+ Ul,
+ Var,
+ Wbr,
+ Xml,
+}
diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/UI/RenderStyle.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/RenderStyle.cs
new file mode 100644
index 000000000..cc2fb91e4
--- /dev/null
+++ b/src/Microsoft.AspNetCore.SystemWebAdapters/UI/RenderStyle.cs
@@ -0,0 +1,10 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Web.UI;
+
+///
+/// Holds information about each style attribute that needs to be rendered.
+/// This is used by the tag rendering API of HtmlTextWriter.
+///
+internal readonly record struct RenderStyle(string Name, string Value, HtmlTextWriterStyle Key);