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()
?
i.e. 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.
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With