Rendering Debug Information In Sitecore MVC Views

This post is a result of a question that was raised in the Sitecore Slack chat room.

It is a Sitecore best practice to separate your HTML into logical parts and assemble your pages using multiple components that each serve a specific purpose.  With Sitecore MVC, you have several options on component types to use.  The most commonly used are View Rendering and Controller Rendering.  When you break up your HTML into small, logical View/Controller Renderings, you’re able to personalize individual parts of the page very easily independent of other parts of the page.  The challenge is if you need to trace down an issue with your HTML – it can be difficult to find what Sitecore component rendered a given block of HTML.

There are several ways that you can inspect your HTML and figure out what Sitecore component rendered a given section of the page.  Here are a few methods that come to mind:

  1. add a CSS class to the top-level HTML element in each View being rendered by Sitecore and use a naming convention that matches between your Sitecore View/Controller Renderings and your CSS classes
  2. manually add HTML comments at the beginning and end of each View being rendered by Sitecore as shown here http://stackoverflow.com/questions/6311463/how-to-get-the-current-view-name-in-asp-net-mvc-3/6311523#6311523
  3. programmatically add HTML comments at the beginning and end of each View being rendered by Sitecore and use a setting to control whether or not these comments are rendered

While options 1 and 2 above are valid options, I’d like to show you how you can implement the 3rd option with minimal code and config changes.

If you’re using Synthesis, you have a similar feature already available to you – https://github.com/kamsar/Synthesis/blob/Sitecore-8.1/Source/Synthesis.Mvc/Pipelines/GetRenderer/RenderingDiagnosticsInjector.cs.

If you’re not using Synthesis, keep reading.

First, we need to create two classes that will append the HTML comments to the rendering arguments – one before the HTML in the View, one after the HTML in the View.  These classes will run once each for every component that is rendered by Sitecore.

AddStartComment.cs

using Sitecore.Configuration;
using Sitecore.Mvc.Pipelines.Response.RenderRendering;

namespace MySolution.Framework.Pipelines.Response.RenderRendering
{
    public class AddStartComment : RenderRenderingProcessor
    {
        public override void Process(RenderRenderingArgs args)
        {
            if (Settings.GetBoolSetting(Constants.Settings.RenderStartEndComments, false))
            {
                args.Writer.WriteLine("");
                args.Writer.WriteLine("<!-- START: {0} -->", args.Rendering.Renderer);
                args.Writer.WriteLine("");
            }
        }
    }
}

The args.Writer object is what will hold the HTML that will ultimately be rendered on the page.  Since the AddStartComment.cs class will be patched before the Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer processor is executed, the args.Writer object is still empty at this point, any lines we add here will be rendered before the actual HTML that will be rendered by the Sitecore View/Controller Rendering.  In other words, these lines will be prepended to the HTML that will be rendered by the Sitecore View/Controller Rendering.

args.Rendering.Renderer is the object that represents the actual Sitecore component being rendered so it has exactly the information we need to add to our HTML so that we can get a better idea of what component rendered a given section of HTML.  There are a lot of useful properties in the args object and I encourage you to take a look at them with the debugger as they may provide some more useful information you may want to output on the page if you’re looking to debug your renderings from the HTML side.

AddEndComment.cs

using Sitecore.Configuration;
using Sitecore.Mvc.Pipelines.Response.RenderRendering;

namespace MySolution.Framework.Pipelines.Response.RenderRendering
{
    public class AddEndComment : RenderRenderingProcessor
    {
        public override void Process(RenderRenderingArgs args)
        {
            if (Settings.GetBoolSetting(Constants.Settings.RenderStartEndComments, false))
            {
                args.Writer.WriteLine("");
                args.Writer.WriteLine("<!-- END: {0} -->", args.Rendering.Renderer);
                args.Writer.WriteLine("");
            }
        }
    }
}

By the time the AddEndComment.cs class runs, the Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer processor has been executed already (as well as our AddStartComment.cs processor) and so whatever lines we add in the AddEndComment.cs class, they get appended to the end of the HTML that will be rendered by the Sitecore View/Controller Rendering.

Next, we need to patch in our new classes before and after the Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer processor:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <mvc.renderRendering>
        <processor type="MySolution.Framework.Pipelines.Response.RenderRendering.AddStartComment, MySolution.Framework" patch:before="processor[@type='Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer, Sitecore.Mvc']"/>
        <processor type="MySolution.Framework.Pipelines.Response.RenderRendering.AddEndComment, MySolution.Framework" patch:after="processor[@type='Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer, Sitecore.Mvc']"/>
      </mvc.renderRendering>
    </pipelines>
    <settings>
      <setting name="RenderStartEndComments" value="true" />
    </settings>
  </sitecore>
</configuration>

In this patch config file, I’m also including a new setting called RenderStartEndComments so that you can easily turn this feature on or off without having to change any code.

With this setting enabled, you’ll now see comments such as these:

from a View Rendering

<!-- START: View: ~/Views/MySolution/Renderings/BodyContent.cshtml -->

<!-- END: View: ~/Views/MySolution/Renderings/BodyContent.cshtml -->

from a Controller Rendering

<!-- START: Controller: MySolution.Web.Controllers.GenericCalloutsListController, MySolution.Web. Action: Index -->

<!-- END: Controller: MySolution.Web.Controllers.GenericCalloutsListController, MySolution.Web. Action: Index -->

That’s it! Now you’ve got comments in your HTML that you can use as reference when you’re trying to debug an issue and want to identify what Sitecore component rendered a given block of HTML.

4 thoughts on “Rendering Debug Information In Sitecore MVC Views

Leave a Reply