title: Adapting a Custom Html Helper for Razor (it uses HtmlTextWriter so returns void)
body: <h2>The Problem</h2>
  
  <p>I have a very nifty menu Html helper written for WebFormViewEngine views.  This engine allows your helpers to return void, and still be able to use:</p>
  
  <pre><code>@Html.Theseus
  </code></pre>
  
  <p>This is great for my helper, because it can then render the menu using HtmlTextWriter, that renders directly to the output stream.</p>
  
  <p>In Razor views, however, the Html helpers are expected to return a value (usually MvcHtmlString) which is what gets added to the output.  Small difference, big consequence.</p>
  
  <p>There is a way around this, as pointed out to me by GvS (see <a href="https://stackoverflow.com/questions/4216736/asp-net-mvc-2-to-mvc-3-custom-html-helpers-in-razor">ASP.NET MVC 2 to MVC 3: Custom Html Helpers in Razor</a>) as follows:</p>
  
  <p>If the helper returns void, then do the following:</p>
  
  <pre><code>@{Html.Theseus;}
  </code></pre>
  
  <p>(Essentially, you are just calling the method, rather than rendering into the view).</p>
  
  <p>Whilst still neat, this is not quite the same as @Html.Theseus.  So...</p>
  
  <p>My code is complex but works very well, so am loath to go through major edits, ie, replacing the HtmlTextWriter with another writer.  A snippet of the code goes like:</p>
  
  <pre><code>writer.AddAttribute(HtmlTextWriterAttribute.Href, n.Url);
  writer.AddAttribute(HtmlTextWriterAttribute.Title, n.Description);
  writer.RenderBeginTag(HtmlTextWriterTag.A);
  writer.WriteEncodedText(n.Title);
  writer.RenderEndTag();
  
  // Recursion, if any
  // Snip off the recursion at this level if specified by depth
  // Use a negative value for depth if you want to render the entire sitemap from the starting node
  
      if ((currentDepth &lt; depth) || (depth &lt; 0))
      {
           if (hasChildNodes)
           {
                // Recursive building starts here
  
                // Open new ul tag for the child nodes 
                // "&lt;ul class='ChildNodesContainer {0} Level{1}'&gt;"; 
                writer.AddAttribute(HtmlTextWriterAttribute.Class, "Level" + currentDepth.ToString());
                writer.RenderBeginTag(HtmlTextWriterTag.Ul);
  
                // BuildMenuLevel calls itself here to 
                // recursively traverse the sitemap hierarchy, 
                // building the menu as I go.
                // Note: this is where I increase the currentDepth variable!
                 BuildChildMenu(currentDepth + 1, depth, n, writer);
  
                // Close ul tag for the child nodes
                writer.RenderEndTag();
            }
      }
  </code></pre>
  
  <p>It wouldn't be fun to re write with TagBuilders.  As it stands, it renders any type of menu, including the "Incremental Navigation" as described in my 4guysfromrolla article:
  <a href="https://web.archive.org/web/20210304123939/https://www.4guysfromrolla.com/articles/060309-1.aspx" rel="nofollow noreferrer">Implementing Incremental Navigation with ASP.NET</a></p>
  
  <h2>The Options:</h2>
  
  <p>I guess I could return an empty MvcHtmlString, but that is pretty much the definition of a hack...</p>
  
  <p>The only alternative is to head off into the sunset and rewrite the helper using the TagBuilder to build each tag, add that to a StringBuilder, then build the next tag, etc, and then use the StringBuilder instance to create the MvcHtmlString.  Seriously ugly, unless I could do something like...  </p>
  
  <h2>The Question:</h2>
  
  <p>Is there a way to:</p>
  
  <p>Stop the HtmlTextWriter rendering to the stream and instead use it like a StringBuilder that at the end of the process I use to create an MvcHtmlString (or HtmlString)?  </p>
  
  <p>Sounds unlikely, even as I write...</p>
  
  <h2>PS:</h2>
  
  <p>The great thing about the HtmlTextWriter is that you can build large quantities of tags, instead of building them one by one as with a TagBuilder.</p>