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