[英]Can you control the order in which the TagBuilder class renders attributes?
I know this is kind of obsessive, but is there a way to control the order that the TagBuilder
class renders the attributes of an HTML tag when you call ToString()
?我知道这有点强迫症,但是有没有一种方法可以控制TagBuilder
类在您调用ToString()
时呈现 HTML 标记属性的顺序?
ie so that即这样
var tb = new TagBuilder("meta");
tb.Attributes.Add("http-equiv", "Content-Type");
tb.Attributes.Add("content", "text/html; charset=utf-8");
tb.ToString(TagRenderMode.SelfClosing)
will return将返回
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
not不是
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
Changing the order that you add the attributes doesn't change it, it seems to be rendering in alphabetical order更改添加属性的顺序不会改变它,它似乎是按字母顺序呈现的
Try using this class, which inherits the TagBuilder and overrides the ToString method, building a SortedDictionary from the Attributes and using that dictionary to render.尝试使用此类继承 TagBuilder 并覆盖 ToString 方法,从属性构建 SortedDictionary 并使用该字典进行呈现。
public class MyTagBuilder : TagBuilder
{
//required to inherit from TagBuilder
public MyTagBuilder(string tagName) : base(tagName){}
//new hides the original ToString(TagRenderMode renderMode)
//The only changes in this method is that all calls to GetAttributesString
//have been changed to GetMyAttributesString
public new string ToString(TagRenderMode renderMode)
{
switch (renderMode)
{
case TagRenderMode.StartTag:
return string.Format(CultureInfo.InvariantCulture, "<{0}{1}>", new object[] { this.TagName, this.GetMyAttributesString() });
case TagRenderMode.EndTag:
return string.Format(CultureInfo.InvariantCulture, "</{0}>", new object[] { this.TagName });
case TagRenderMode.SelfClosing:
return string.Format(CultureInfo.InvariantCulture, "<{0}{1} />", new object[] { this.TagName, this.GetMyAttributesString() });
}
return string.Format(CultureInfo.InvariantCulture, "<{0}{1}>{2}</{0}>", new object[] { this.TagName, this.GetMyAttributesString(), this.InnerHtml });
}
//Implement GetMyAttributesString where the Attributes are changed to a SortedDictionary
private string GetMyAttributesString()
{
var builder = new StringBuilder();
var myDictionary = new SortedDictionary<string, string>(); //new
foreach (KeyValuePair<string, string> pair in this.Attributes) //new
{ //new
myDictionary.Add(pair.Key, pair.Value); //new
} //new
//foreach (KeyValuePair<string, string> pair in this.Attributes)
foreach (KeyValuePair<string, string> pair in myDictionary) //changed
{
string key = pair.Key;
if (!string.Equals(key, "id", StringComparison.Ordinal) || !string.IsNullOrEmpty(pair.Value))
{
string str2 = HttpUtility.HtmlAttributeEncode(pair.Value);
builder.AppendFormat(CultureInfo.InvariantCulture, " {0}=\"{1}\"", new object[] { key, str2 });
}
}
return builder.ToString();
}
}
I disassembled TagBuilder.ToString()
with Reflector, and this is the key bit of code:我用 Reflector 反汇编了TagBuilder.ToString()
,这是代码的关键部分:
foreach (KeyValuePair<string, string> pair in this.Attributes)
{
string key = pair.Key;
string str2 = HttpUtility.HtmlAttributeEncode(pair.Value);
builder.AppendFormat(CultureInfo.InvariantCulture, " {0}=\"{1}\"", new object[] { key, str2 });
}
So I would say not - this.Attributes
is an IDictionary<string,string>
interface, when enumerating over that "the order in which the items are returned is undefined," according to MSDN.所以我会说不是 - this.Attributes
是一个IDictionary<string,string>
接口,根据 MSDN 的说法,当枚举“返回项目的顺序是未定义的”时。
I did not want to override all that code to modify the sort behaviour so I changed the Attributes-property to a regular unsorted Dictionary with reflection instead我不想覆盖所有代码来修改排序行为,所以我将 Attributes-property 更改为带有反射的常规未排序字典
private class MyTagBuilder: TagBuilder
{
private static readonly MethodInfo tagBuilderAttrSetMethod = typeof(TagBuilder).GetProperty(nameof(Attributes)).SetMethod;
public MyTagBuilder(string tagName) : base(tagName)
{
// TagBuilder internally uses SortedDictionary, render attributes according to the order they are added instead
tagBuilderAttrSetMethod.Invoke(this, new object[] { new Dictionary<string, string>() });
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.