A .NET MVC Helper to create HTML wrapping elements

In HTML when you want to create a box around some content with rounded corners or some other nice feature it would be nice if you could just wrap that content in a <div> or a <section> tag and CSS would do the rest. However this rarely seems to be the case, particularly if you want the HTML to render well in older browsers. The views in my latest .NET MVC 3 project were full of repeated opening and closing sections of HTML for something that we called a chunk, which is just our word for a box with rounded corners that groups together related elements on the page. Sometimes a chunk has a title, sometimes it doesn't.

Really any repeated code like this should be in some sport of template or helper, to keep the code clean and make it easy to change in the future. But, as there was opening code and closing code there would need to be two templates and this seemed messy. Inspired by how .NET MVC writes the opening and closing tags for forms on the page I thought that using the using statement and a chunk class that implemented IDisposable might be the way to go.

The razor code

The aim was to have razor code in my view that looked like this:

@using(Html.BeginChunk("Optional chunk title"))
{
    <p>Normal HTML content.</p>
}

The BeginChunk helper

The BeginChunk helper returns an IDisposable class whose Dispose method is called when the closing brace is reached. The helper code looks like this:

using System;
using System.Web.Mvc;

namespace NogginBox.MVC.Extensions.Helpers
{
    public static class ChunkHelpers
    {
        public static Chunk BeginChunk(this HtmlHelper html, String title = null)
        {
            var htmlText = (title != null)
               ? "<div class=\"chunk\"><h2>" + title + "</h2><div class=\"chunk-inner\">"
               : "<div class=\"chunk\"><div class=\"chunk-inner\">";

            html.ViewContext.Writer.Write(htmlText);

            return new Chunk(html);
        }

        public static void EndChunk(this HtmlHelper html)
        {
            html.ViewContext.Writer.Write("</div><div class=\"chunk-bottom\"></div></div>");
         }
    }
}

The Chunk class

The actual chunk class is very simple. The helper does most of the work. The chunk class looks like this:

using System;
using System.Web.Mvc;

namespace Pianola.MVC.Extensions.Helpers
{
    public class Chunk : IDisposable
    {
        private readonly HtmlHelper _html;

        public Chunk(HtmlHelper html)
        {
            _html = html;
        }

        public void Dispose()
        {
            _html.EndChunk();
        }
    }
}

And that's it. Using this helper has resulted in my views being much cleaner and far easier to modify.

Tore Aurstad said

said 21 December 2011 08:20:10 Terrific advice! I will try it out myself, as I also need to create grouping box and did think about going for the @Html.BeginForm strategy myself. Thanks to you, I can see clearly now and its not raining :-)

Cheers from Norway and merry X-mas!

Red Bucket Web said

Perfect. Exactly what I needed. Thanks.