views:

94

answers:

2

I am migrating some old code where HtmlTextWriter is used extensively to render UI elements.

I am migrating the code to use ASP.NET MVC 1.0. As far as I am aware, I am not using any of the HtmlTextWriter specific function (such as indentation).

Currently, I am using a wrapper method to return string generated by the HtmlTextWriter as follow:

var sw = new StringWriter();
var xhtmlTextWriter = new XhtmlTextWriter(sw);
GenerateHtml(xhtmlTextWriter);
return sw.ToString();

My questions are:

  1. I am trying to get HtmlTextWriter instance from ASP.NET MVC View, but apparently even the HtmlHelper does not use this. Do I miss anything?

  2. Each call to GenerateHtml will generated small HTML pieces, generally not bigger than 1000 characters, but there can be a lot of calls. Is it worth rewriting the HtmlTextWriter dependent code into StringBuilder? Or instead, what about creating a HtmlTextWriter instance which will be used on all calls (and flushed at the end of the iterations).

A: 

I have a demo app here which shows how to do this in an MVC app.

Here's a code sample, from that post.

    public static string DayPilot(
        this HtmlHelper helper,
        DayPilotData model,
        DayPilotViewOptions options)
    {
        var calendar = new DayPilotCalendar();
        if (model != null)
        {
            model.CopyTo(calendar);
        }
        if (options != null)
        {
            options.CopyTo(calendar);
        }
        var sb = new System.Text.StringBuilder();
        sb.Append("<div class=\"dayPilot\">"); // allows working around td cellpadding bug in css
        using (var sw = new System.IO.StringWriter(sb))
        {
            using (var tw = new HtmlTextWriter(sw))
            {
                calendar.RenderControl(tw);
            }
        }
        sb.Append("</div>");
        return sb.ToString();
    }

Regarding #2, if it ain't broke...

Craig Stuntz
...don't fix it. Yes, but my main concern is that the code assumes the HtmlTextWriter is backed by a stream and not a StringWriter/StringBuilder. Having a different backend may severely affect performance and might be perceived as "broken" by the end user.
Adrian Godong
If profiling proves that it's actually a bottleneck, then by all means go fix it.
Craig Stuntz
A: 

Instead of creating a StringBuider and StringWriter I think using the helper.ViewContext.writer will work.

Then the above sample code would be:

var calendar = new DayPilotCalendar();
if( model != null )
   {
   model.CopyTo( calendar );
   }
if( options != null )
   {
   options.CopyTo( calendar );
   }

HtmlTextWriter writer = new HtmlTextWriter( helper.ViewContext.Writer );

writer.AddAttribute( HtmlTextWriterAttribute.Class, "dayPilot" );
writer.RenderBeginTag( HtmlTextWriterTag.Div );
calendar.RenderControl( writer );
writer.RenderEndTag();  // Close DIV

return( null );         // Don't need to return anything.

Disclaimer: So far I've only tried using the helper.ViewContext.Writer to produce a <UL> list. It worked fine. Haven't tried it to render controls.

Thomas Hamilton