Handling the situation where scItemPath does not exist in Sitecore MVC

What happens if the scItemPath specified in your route does not exist in Sitecore? In this post i'm going to discuss how I handle this situation.

Here is a sample route from Sitecore's MVC documentation.   (see Section 4.1)

       

      // matches the item '/home/blogPosts/{blogNo}' 
routes.MapRoute("example2", "blog/{blogNo}", new { scItemPath = 
 "/home/blogPosts/{blogNo}" }); 


       
 

But what happens when the blog number doesn't exist?   What page will Sitecore show?  What if the user has a link to an old blog post that you have archived or someone links to a blog post using the wrong number by accident?

What I wanted was a new route value that specified where to go when the path resolved by scItemPath is not found.  So I created the scNoItemFound value.

       

      // matches the item '/home/blogPosts/{blogNo}' 
routes.MapRoute("example2", "blog/{blogNo}", new { scItemPath = 
 "/home/blogPosts/{blogNo}",  scNoItemFound = new Sitecore.Data.ID("some guid") }); 


       
 

Reading the MVC documentation you can discover what the MVC pipelines are.     It became apparent to me I needed to create a a new processor somewhere inside the getPageItem pipeline.

Using Telerik's JustDecompile, I looked in the Sitecore.MVC assembly at the classes inside of the Sitecore.Mvc.Pipelines.Response.GetPageItem namespace.

I found the GetFromRouteValue class looks at the scItemPath route value.    Lucky for me, the ResolveItem method was marked as protected (thanks Sitecore :-) ).

So I  created a new class which extends the GetFromRouteValue class and overrides the ResolveItem method.

Here is the class:
       

        public class GetFromRouteValueExtended : Sitecore.Mvc.Pipelines.Response.GetPageItem.GetFromRouteValue
    {
        protected override Sitecore.Data.Items.Item ResolveItem(Sitecore.Mvc.Pipelines.Response.GetPageItem.GetPageItemArgs args)
        {
            var item = base.ResolveItem(args);

            if (item == null)
            {
                var routeValue = args.RouteData.Values["scNoItemFound"];

                if (routeValue is Sitecore.Data.ID)
                {
                    item = Sitecore.Context.Database.GetItem(routeValue as Sitecore.Data.ID);
                }
            }
            return item;
        }
    }

       
 

You can now replace the GetFromRouteValue processsor in the Sitecore.MVC.config file or use the patch syntax in your own configuration file to replace the GetFromRouteValue processor.


Comments

  1. Hi Rob,
    Your post was too useful and i am almost at my goal. I have followed every steps that you provided and replaced GetFromRouteValue processor. When i am running my application, i am not able to get debug on override method.
    Can you please help me in this to identify where exactly i am mistaking?

    ReplyDelete

Post a Comment

Popular posts from this blog

Why I chose Selenium WebDriver instead of Telerik's free testing framework

Displaying shared content across multiple Sites