Custom controls can use this for example to render out a span tag:
writer.RenderBeginTag(HtmlTextWriterTag.Span);  
writer.Write(Text);  
writer.RenderEndTag();
Ok, why can't I just do this:
writer.Write("<span>");
writer.Write(Text);
writer.Write(</span>");
this way I can actually see it rather than reading HtlmlTextWriter tags all over the place and also tweak any of the mark-up easily such as adding cs classes, ids, or whaetver to the tags. And if you say it's faster to type because of Intellisense, is that about the only reason to use RenderBegin and RenderEnd? that's not much of a case.
Here where I work, we use the RenderBeginTag()/RenderEndTag() technique exclusively in our large suite of custom controls, and generally eschew calling Write("") directly. There are several good reasons:
As Patrick noted, by using RenderBeginTag()/RenderEndTag(), you can't accidentally emit elements with typos in their names.
With RenderBeginTag()/RenderEndTag(), the ASP.NET runtime will tell you if you've emitted bad markup --- if you forget a matching RenderEndTag() for a previous RenderBeginTag(), ASP.NET will throw an exception on your page. This makes it really hard to have an unclosed element.
Likewise, you can't mismatch closing tags this way either --- <div> must be ended with </div>, and cannot be accidentally ended with </span>.
The AddAttribute() method allows rendering of complex single elements to be divided up into logical chunks: This method adds appropriate CSS classnames, that one correctly computes the value attribute, and that method over there adds a special custom foo attribute. Doing that kind of element assembly with a StringBuilder is possible, but it can be more error-prone.
Tools can automatically and reliably find usages for you. If I want to know every line of code in our controls that emits, say, a span, I can just search for usages of HtmlTextWriterTag.Span. Searching on "<span" is a bit more error-prone, and may miss some usages if the "<" is written out separately from the "span" (as would be the case in a control that switches back and forth between a span and an a element depending an Enabled flag).
Extension methods can expand on the AddAttribute() method to add attributes in more sophisticated ways: We have an AddNonNullClassnames() extension method that constructs the class attribute from any of the multiple strings that are passed in that are neither null nor empty, and it's proven a godsend in building complicated controls that are still fully style-able via CSS.
ASP.NET will attempt (attempt, I say) to perform proper indentation of the output based on how deeply nested the elements are. It doesn't always succeed, but its result is better for debugging than just having all your HTML emitted on one line, or smashed up against the left column.
(For the record, we use pure-CSS layouts --- no table-based layouts on my watch, thank you! --- and these techniques have helped with that too.)
I was pretty resistive of this at first myself --- it's long, and wordy, and proprietary, just like you noted, and coming from an open-source background I found it pretty stinky at first --- but after three years of working with it, I can say that it makes the code more flexible, makes certain complex operations easier, and adds a surprising amount of safety and cleanliness to the output.
You will have less typos (since "<spsn>" won't give a compile error, but HtmlTextWriterTag.Spsn will).
And perhaps not in this case, but using defined Tags will make it easier to apply changes later in code. If for some strange reason, span will be named something else, the value of the tag Span can easily be changed at one place, effectively changing all places, instead of manually changing every place where you used the string value...
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