James
James

Reputation: 7533

How can I auto-format Razor output with indentation and line breaks?

I have a few Razor pages with lots of conditional logic, loops, partial views etc. It's easy to keep the output markup semantically correct, but more difficult to format it with the right indentation and line breaks. How could I do this automatically at runtime? Is there a module or Razor extension?

Please don't say Right click -> Format selection. To be clear, I want to avoid having to think about formatting when I write the Razor pages. I want my Razor markup to be laid out in a way that makes sense to developers (indenting inside server-side blocks, for example) - but the rendered HTML to be 'prettified' for the odd person who clicks 'View source'. (I'm not worried about increasing the size of the output because I'm using gzip/deflate.)

Upvotes: 3

Views: 1656

Answers (1)

Lucas Reis
Lucas Reis

Reputation: 741

You can use a library like TidyNet ( http://sourceforge.net/projects/tidynet/ ), an implement an ActionFilter:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    if (filterContext.Result is ViewResult)
    {
        var tidy = new Tidy
            {
                Options =
                    {
                        DocType = DocType,
                        DropFontTags = DropFontTags,
                        LogicalEmphasis = LogicalEmphasis,
                        XmlOut = XmlOut,
                        Xhtml = Xhtml,
                        IndentContent = IndentContent,
                        HideEndTags = HideEndTags,
                        MakeClean = MakeClean,
                        TidyMark = TidyMark,
                    }
                };

        filterContext.RequestContext.HttpContext.Response.Filter =
            new HtmlTidyFilter(filterContext.RequestContext.HttpContext.Response.Filter, tidy);
    }
}

The algorithm of the filter:

public override void Write(byte[] buffer, int offset, int count)
{
    var data = new byte[count];
    Buffer.BlockCopy(buffer, offset, data, 0, count);
    string html = Encoding.Default.GetString(buffer);

    using (var input = new MemoryStream())
    {
        using (var output = new MemoryStream())
        {
            byte[] byteArray = Encoding.UTF8.GetBytes(html);
            input.Write(byteArray, 0, byteArray.Length);
            input.Position = 0;
            _tidy.Parse(input, output, new TidyMessageCollection());

            string result = Encoding.UTF8.GetString(output.ToArray());

            byte[] outdata = Encoding.Default.GetBytes(result);
            _stream.Write(outdata, 0, outdata.GetLength(0));
        }
    }
} 

And then you just plug it into the Controller:

[TidyHtml]
public class AnyController : Controller

Voilá! ;)

I learned it from this source: http://blog.aquabirdconsulting.com/2009/10/28/asp-net-mvc-clean-html/

Upvotes: 4

Related Questions