Why use TagBuilder instead of StringBuilder?

22,952

Solution 1

TagBuilder is a class that specially designed for creating html tags and their content. You are right saying that result will be anyway a string and of course you still can use StringBuilder and the result will be the same, but you can do things easier with TagBuilder. Lets say you need to generate a tag:

<a href='http://www.stackoverflow.com' class='coolLink'/>

Using StringBuilder you need to write something like this:

var sb = new StringBuilder();
sb.Append("<a href='");
sb.Append(link);
sb.Append("' class = '");
sb.Append(ccsClass);
sb.Append("'/>");
sb.ToString();

It is not very cool, isn’t it? And compare how you can build it using TagBuilder;

var tb = new TagBuilder("a");
tb.MergeAttribute("href",link);
tb.AddCssClass(cssClass);
tb.ToString(TagRenderMode.SelfClosing);

Isn't that better?

Solution 2

It's just convenience. From this tutorial:

You don’t really need to use the TagBuilder class. You could use a StringBuilder class instead. However, the TagBuilder class makes your life a little easier.

Look at the methods on TagBuilder, and think about whether they give you value. would you want to do the same thing yourself manually in StringBuilder every time? Is there escaping that it does for you? Attribute merging, etc? Is the resulting code easier to read, making it clearer that you're building a tag rather than some arbitrary string?

Solution 3

There's a point that the other answers have missed so far. If you return TagBuilder from an extension method you can continue to add attributes in your view. Let's say you were returning a table from an Html helper and you want to add a class attribute. If you're using a StringBuilder you need to pass the class in as a parameter.

public static string Table(...., string @class)
{
    ...
    sb.AppendFormat("class='{0}", @class);
    ...
}

// In the view
<%: Html.Table(someParams, "fancy") %>

But adding a class attribute to an HTML tag is not the concern of an extension method that creates a table! If we switch to a semantic model (TagBuilder) for generating the HTML, we can add the class attribute outside of the table method.

public static TagBuilder Table(....)
{
    ...
    return tag;
}

// In the view
<%: Html.Table(someParams).AddCssClass("fancy") %>

In addition to TagBuilder, you might want to check out FubuMVC's HtmlTags library. It's a much better model for generating HTML. I have some more details on blog.

Solution 4

aren't they generating the same thing??

Well, sure, but that shouldn't be a deterrent, should it? One class is designed for something more specific than the other, so it offers a greater level of convenience.

I could ask: why use a StringBuilder? Why not a List<char>? Couldn't I generate the same thing from either?

Going one step further: why even a List<char>? Why not just a char[], the resizing/manipulation of which I can control myself? I can still totally create a string from a char[].

In fact, all I really need is a char* and an int (for length). Right?

My point is just that if a class is available for specialized functionality that you can use, it makes sense to use it if you ask me.

Solution 5

As it is mentioned in the other posts, TagBuilder brings some convenience. But you should consider that TagBuilder and StringBuilder may does not produce the same result. TagBuilder applies html encoding, but StringBuilder doesn't. So it is safer to use TagBuilder to overcome vulnerabilies that may be exploited via XSS attack.

Share:
22,952
DaveDev
Author by

DaveDev

Updated on July 09, 2022

Comments

  • DaveDev
    DaveDev almost 2 years

    what's the difference in using tag builder and string builder to create a table in a htmlhelper class, or using the HtmlTable?

    aren't they generating the same thing??

  • Don
    Don about 14 years
    For simple tags as per above I prefer sb.AppendFormat("<a href='{0}' class = '{1}'/>", link, cssClass); but the methods on TagBuilder are really neat if one needs more complex tags.
  • Rup
    Rup about 14 years
    Note he asked about building a table, i.e. he's probably nesting table, tbody and then multiple trs and tds. Won't he need one tagbuilder for each of those? I expect that'll get a lot messier than the equivalent stringbuilder.
  • queen3
    queen3 about 14 years
    "<a href='" + link + "' class='" + class + "' />" is even more cleaner. And it's fast because 1) string concatenation is quite fast, with end-result being single string anyway, and 2) don't optimize prematurely. For more complex cases (like tables) I'd suggest templating engine like Spark. I've seen sources that use TagBuilder and that's still hard to understand.
  • Ryan
    Ryan about 14 years
    @Rup Actually if you make the right extension methods it's actually much cleaner to use a semantic model like TagBuilder for generating nested tags.
  • ATL_DEV
    ATL_DEV about 12 years
    I think using TagBuilder defeats the purpose of MVC. You're mixing code and markup for the sake of brevity at the expense of easier modification.
  • ATL_DEV
    ATL_DEV about 12 years
    Why not use StringBuilder to build your attributes and spit out the tags as needed like so: <a href='stackoverflow.com' @attributes />
  • Daniel Little
    Daniel Little over 11 years
    @Joel Rodgers TagBuilder has it's place in HtmlHelpers
  • Chris Marisic
    Chris Marisic over 9 years
    And some point you'll get angry at tag builder and implement your own where you mostly reuse tag builder.
  • Patrick McDonald
    Patrick McDonald over 9 years
    "<a href='\{link}' class='\{cssClass}'/>" is even cleaner, but does not scale like using a TagBuilder does
  • a11smiles
    a11smiles over 9 years
    @queen3 Your example is not best practice as it is a very poor habit to concatenate strings regardless of their length. Strings are placed on the heap where StringBuilder uses the stack. Concatenating string means your app is reallocating new heap resources upon every string addition and the previous allocations are left sitting out their until .NET decides to garbage collect = wasted memory.
  • queen3
    queen3 over 9 years
    @Joshua See stackoverflow.com/questions/21078/… for explanation of when + is better than StringBuilder as in my example.
  • Casey
    Casey over 9 years
    @ChrisMarisic TagBuilder isn't a sealed class. You can see a coupable chainable derived classes floating around on the Web.
  • Casey
    Casey over 9 years
    @JoelRodgers I think if your template has enough conditional stuff in it that it's starting to look more like C# code than HTML then the tag builders start to seem like they make a lot of sense.
  • Chris Marisic
    Chris Marisic over 9 years
    @emodendroket the tag builder is highly opinionated and anti-extensible, you'll find out if you ever try to extend it. Then you'll copy paste the source and make your own instead.
  • Casey
    Casey over 9 years
    @ChrisMarisic Well, I have, and that wasn't my experience, but that's fine.