5 May 2015

Passing Invalid ID in the Rendering Datasource Break your page

Using Sitecore 8 MVC and GlassMapper has been awesome (Thanks to Mike Edwards great work). This is one of the must have for Sitecore MVC. I usually have my Rendering Datasource field pointing at a "Data" Item on the tree:


On the View code I can then bind my view with the Model using GlassMapper as per the following Code:

@inherits Glass.Mapper.Sc.Web.Mvc.GlassView<DPE.Data.Interfaces.SiteSettings.ISiteSettings>

I like to use Interfaces when defining the Models...

While this is great and working correctly when all is setup correctly, I have had a small issue on a latest project where editors deleted the datasource item without removing the links. Which left the Presentation of the item with a broken link:



Although this was quite simple to fix and instruct the client to select the option to either remove the links and/or editing the links manually. This was pointing at another case scenario:

what if you forgot to publish the data source item... Indeed in this situation you will end up with the same broken link in your datasource field on the web database and it will break the page with the following error:



The issue there is that sitecore is trying to create the default model during the pipeline action:

Sitecore.Mvc.Pipelines.Response.GetModel.CreateDefaultRenderingModel, Sitecore.Mvc

While trying to implement a custom action to replace the above pipeline, I found this great post from Hiral Desai. Really great source of information to implement the way around the issue:

The work around was quite simple: replacing the GetViewRenderer pipeline action. In order to do that we need to add the following config entry in our custom patch config files:


  < sitecore>
    
      
        
             
    
  

Then on the code side, we need to implement our new pipeline acttion with the following code:
public class GetViewRendererWithItemValidation : GetViewRenderer
    {        
        protected override Renderer GetRenderer(Rendering rendering, GetRendererArgs args)
        {           
            var viewRenderer = base.GetRenderer(rendering, args) as ViewRenderer;
            if (viewRenderer == null)
                return null;

            // Ignore item check when in page editor
            // Also this will break if the item for the datasource has been deleted without removing the link.
            if (Context.PageMode.IsPageEditor || Context.PageMode.IsPageEditorEditing)
                return viewRenderer;

            // Override renderer to null when there is an unpublished item refererenced by underlying view
            return viewRenderer.Rendering.Item != null && viewRenderer.Rendering.RenderingItem.InnerItem != null
                ? viewRenderer
                : null;
        }
    }

Hoping that will help anyone.


No comments:

Post a Comment