Contact   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

HtmlTextWriter Musings


Ok, so I’m trying to be a good ASP.NET citizen and write out my control output through the verbosity that is the HtmlTextWriter interface. All is well, but I keep running into the issue of not being able to quite figure out how to write out a <br /> tag using the proper writer code.

 

My first guess would be:

 

writer.RenderBeginTag(HtmlTextWriterTag.Br);

writer.RenderEndTag();

 

but that’s not getting the expected results:

<br>

</br>

 

The right way to do this is:

 

writer.WriteBeginTag("br");

writer.Write(HtmlTextWriter.SelfClosingTagEnd);

 

which properly generates:

 

<br />

 

But this got me thinking – isn’t this basically just like hardcoding the value as:

 

writer.Write("<br />");

 

In both cases I’m actually forcing the full <br /> tag to be explicitly written regardless of the type of output generated.

 

I’m just thinking out loud here. The reason for using the HtmlTextWriter interface over just building a string supposedly is that you can apply different rendering adapters to the output. Basically a different HtmlTextWriter can be passed and that writer potentially can interpret the more generic HtmlTextWriter syntax into adaptable Html/XHtml and potentially WAP or whatever.

 

But writing code like the above basically defeats this. Question is, what’s the right way to write this so it would be adaptive?

 

Further upon checking a little closer my pages are set up to use XHTML as the page layout schema. Yet when I checked the HtmlTextWriter type passed to my control in this case, it’s being passed as an HtmlTextWriter rather than the expected XHtmlTextWriter…

 

I haven’t looked at the details in 2.0, but how does ASP.NET decide when to use the XHtmlTextWriter? It seems it would have to look at the page in combination to the user agent in order to determine the writer to use... 

 

I was searching around regarding a few of these topics and I ran into a few interesting posts (here’s one) that try to tell you that all non-HtmlTextWriter output is evil. In many cases the point made is that adaptive rendering is not available to plain written output.

 

Duh – if you create ASPX pages that have static markup text that you yourself create on the page, no amount of adaptive rendering will help you. If you have a couple of Response.Write() statements or you use a StringBuilder to output text to a literal control, that’s hardly going to change those same dynamics…

 

While I certainly would recommend using an HtmlTextWriter when possible let’s not forget that writing the HTW code is a heck of a bit more involved that spitting out a string. It depends entirely on the scenario involved. Certainly if you build a resusable control it’s a good idea to use a HTW, but on page code that is tied to a very specific HTML schema anyway the value of using a HTW is much less obvious…

Make Donation


Feedback for this Post

 
# re: HtmlTextWriter Musings
by DuncS June 09, 2006 @ 8:00am
Too true Rick. If you're a control vendor - then definitely use HTW so that we have another extensibilty point in being able to Render() it using a custom, sub-classed HTW. But for the rest of rest of us: do the simplest, most easily readable/maintainable thing (eg, writer.Write("<br/>")), because inevitably: YAGNI.
# re: HtmlTextWriter Musings
by AsbjornM June 09, 2006 @ 9:36am
Reflector tells me that you have an method called WriteBreak, in both HtmlTextWriter and XHtmlTextWriter, in HtmlTextWriter it is implemented like this:

this.Write("<br />");
and in XHtmlTextWriter it is implemented like this:
this.WriteFullBeginTag("br/");

so..
# re: HtmlTextWriter Musings
by Jeff Atwood June 09, 2006 @ 10:49am
Yeah, I agree with DuncS. Do the simplest thing that works. The idea that you can flip a switch and have your controls render correctly from Lynx to Firefox is a pipe dream anyway..

Here's a good eaxmple from the comments to the cazzu post:

--
Response.write("<b>Something goes wrong<br/><textarea rows=\"5\" cols=\"40\">Some details</TextArea></b>");
--

Compared to..

--
string s = "Some details";
HtmlTextWriter mhw = new HtmlTextWriter(myStringWriter);
mhw.RenderBeginTag(HtmlTextWriterTag.B);
mhw.Write("Something goes wrong");
mhw.RenderBeginTag(HtmlTextWriterTag.Br);
mhw.RenderEndTag();
mhw.AddAttribute("rows", "5");
mhw.AddAttribute("cols", "40");
mhw.RenderBeginTag(HtmlTextWriterTag.Textarea);
mhw.Write(s);
mhw.RenderEndTag();
mhw.RenderEndTag();
ErrorMessage.Visible = true;
mhw.Flush();
myStringWriter.Flush();
--

That is just WAYYY too much code for something so simple.
# re: HtmlTextWriter Musings
by Bertrand Le Roy June 09, 2006 @ 12:08pm
Errr, WriteBreak?
# re: HtmlTextWriter Musings
by Steve from Pleasant Hill June 09, 2006 @ 12:22pm
"but on page code that is tied to a very specific HTML schema anyway the value of using a HTW is much less obvious…"

amen
# re: HtmlTextWriter Musings
by AsbjornM June 09, 2006 @ 12:49pm
Well, He is first asking about how to write the BR, so, when looking at the used classes you will find:

public override void WriteBreak()
{
this.WriteFullBeginTag("br/");
}
# re: HtmlTextWriter Musings
by Peter Bromberg June 09, 2006 @ 2:36pm
This reminds me of the old joke about the two strings that stroll up to the bar.

The first string says "I'll have a bee oksdoka/ry".

Second string says to the bartender, "Don't mind my buddy - he isn't null-terminated."

:-)
# re: HtmlTextWriter Musings
by Rick Strahl June 09, 2006 @ 3:04pm
Jeff, yes that is my thinking as well. Not to mention the potential for screwing up that code and spending a significant amount of time trying to debug the nesting and all that does to the maintainability of the code <g>...

And Bertrand - yup, sometimes I don't see the forest for the trees <g>. I did miss that, but the general point still applies.
# re: HtmlTextWriter Musings
by Anatoly Lubarsky June 09, 2006 @ 8:59pm
Sometimes you have to render attributes so
Write("< br />") can not be generic.

And BTW, br can also have attributes, so WriteBreak seems like silly for me, not to mention the name of the function
# re: HtmlTextWriter Musings
by Bertrand Le Roy June 10, 2006 @ 12:08am
I'm not sure I see your point actually. The textwriter approach should be used by control developers so that the control of what to render is in the hands of the page developer.
The page developer is responsible for the code of his page, and is kindly asking the controls he's using to use the right textwriter. If the controls bypass this and assume their favorite flavor of HTML, it just makes the page developer's life more difficult.
# re: HtmlTextWriter Musings
by Rick Strahl June 10, 2006 @ 12:17am
Bertrand - in my case I am actually writing code in a control - otherwise I wouldn't bother and just fire away with a StringBuilder <g>... But even in controls sometimes it's difficult to find the right combination of commands to use. Maybe <hr /> is a better example since there's no built in function for it. HTW has many overlapping methods that have very similar functionality. Truth is everytime I write HTW code I have to go dig out some code I previously wrote to jog my memory exactly how it works <s> - you know, old age is setting in. As Anatoly points out there's, uh, some inconsistency in the layout of the interface...

Obviously both methods of raw output or HTW have their place. I just seriously wonder, as Jeff pointed out, how much of the holy grail of adaptive rendering we can really expect just through the magic of HTW... I'm doing the right thing just in case, although I'm not 100% clear what it's buying me other than more code complexity.

So, anybody know when XHtmlTextWriter is used and how it actually passes this thing? In the few tests I've run on a variety of pages I can't ever see an XHtmlTextWriter passed even though the pages are? What actually triggers this writer?
# re: HtmlTextWriter Musings
by Bertrand Le Roy June 12, 2006 @ 1:29pm
The XHTML text writer is only used on some devices that require a strict dialect of XHTML. It is triggered by browsercaps.
The textwriters are certainly no holy grail, just part of the things you need to get good adaptative rendering. Other important parts are browsercaps and adapters.
# Coding Horror: When Object-Oriented Rendering is Too Much Code
by Coding Horror February 21, 2007 @ 6:18pm
# re: HtmlTextWriter Musings
by kelasings October 19, 2007 @ 5:10pm
writer.WriteBreak(); works just great for me. :-)
 


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2014