Dusty Eves

dusty.eves@techno-babble.net

Sitecore Architect with Paragon Consulting

Intro to Sitecore MVC for the Sitecore Veteran

Introduction

So you’ve spent a few year in the Sitecore trenches, learning all it’s eccentricities and the subtle nuances.  Through sweat and toil you’ve learned to make it dance to you tune and laugh manically with the awesome power of Sitecore at your fingertips, muwhahahaha!!!

But now enter Sitecore MVC and we’ve a whole new slew of eccentricities and subtle nuances.  And what’s worse if you’re not familiar with those MVC subtleties you’ll find what error messages you get to be dramatically unhelpful.  If any of this rings a bell then this article is for you.  We’re going to dive into the subtle nuances of Sitecore MVC for the Sitecore Veteran focusing on pitfalls and resolving errors.  As there are many articles that provide much better introductions to MVC that I could provide, this article assumes at least some passing familiarity with MVC.  If you’re completely new to MVC, I recommend the W3Schools tutorial on the subject.  Additionally Joe Stevens has a good “hello world” tutorial for Sitecore MVC here: Sitecore MVC Tutorial.

Basic Presentation

The first thing we need a handle on in Sitecore MVC, is what is the same and what is different.  The presentation model, that is to say the fundamental way we manage presentation in Sitecore has not change much.  Our lout is still a layout item, but rather than the path pointing to an aspx file it will point to a cshtml file.  When defining presentation for a Sitecore item we provide Sitecore with the same information that we’ve provided in the past.  A layout, and a list of renderings assigned to placeholders and potentially having data sources.

What is different is in the way that presentation is defined.  We mostly will use one of two type of presentation, View renderings and Controller renderings.  View renderings function similar to sub-layouts that have no code behind.  View renderings are defined by pointers to the cshtml file and quite often a model definition.  Controller renderings can be thought of as pointers to a stand-alone code-behind.  The controller contains (and can vary) what cshtml or view it returns as part of the controller action.

View Renderings

Again view renderings are like sub-layouts without code behinds.  Start by inserting a new view rendering.  Unlike sub-layout Sitecore doesn’t try to create the initial code artifacts for you.  First field of concern is the path.  Quite straight-forward, this is the location for the view.  A difference in MVC is that a fully explicated path isn’t necessarily required, as the MVC engine will scan defined locations in search of the view.  None the less it’s generally good practice to use fully qualified paths.  A wrong path will get you the following error:

Server Error in ‘/’ Application.


The partial view ‘/views/renderers/TestViewRendering.cshtml’ was not found or no view engine supports the searched locations. The following locations were searched:
/views/renderers/TestViewRendering.cshtml

Description:
An unhandled exception occurred. Exception Details:
System.InvalidOperationException: The partial view ‘/views/renderers/TestViewRendering.cshtml’ was not found or no view engine supports the searched locations. The following locations were searched:

/views/renderers/TestViewRendering.cshtml

Source Error:

Line 17:     <div id="header">
Line 18: 
Line 19:         @Html.Sitecore().Placeholder("header")
Line 20:     </div>
Line 21:     <div id="content">

View Rendering Model

The other important facet of the View Rendering is the model.  Adding a model definition in the cshtml file isn’t enough.  The model also needs to be defined on the rendering.  Models are defined in items at /sitecore/layouts/models and the renderings the point to the model definition items.  The model definition consists of a single field to which you provide a fully qualified class and assembly in standard Microsoft type/assembly notation  (i.e.  “MVCIntro.Models.ContentFeature, MVCIntro.Models”)  If and when you ever find yourself looking at the following error it tends to indicated the model is not defined on the rendering or at least not defined correctly.

Server Error in ‘/’ Application.


The model item passed into the dictionary is of type ‘Sitecore.Mvc.Presentation.RenderingModel’, but this dictionary requires a model item of type ‘MVCIntro.Models.ContentFeature’.

Description:
An unhandled exception occurred.
Exception Details:
System.InvalidOperationException: The model item passed into the dictionary is of type ‘Sitecore.Mvc.Presentation.RenderingModel’, but this dictionary requires a model item of type ‘BranchingIA.Models.GlassBase’.
Source Error:

Line 17:     <div id="header">
Line 18: 
Line 19:         @Html.Sitecore().Placeholder("header")
Line 20:     </div>
Line 21:     <div id="content">

Controller Renderings

As said Controller Renderings are essentially code behinds without ASPX pages.  The way a Sitecore controller rendering works is the rendering defintion has two key fields, the Controller and the Controller Action. The tricky part about setting up the controllers is for those new to MVC the error messages don’t seem to shed much light on the source of the issue. Below is one of the most common errors when setting up a controller:

Server Error in ‘/’ Application.


The controller for path ‘/’ was not found or does not implement IController.

Description:
An unhandled exception occurred.
Exception Details:
Sitecore.Mvc.Diagnostics.ExceptionWrapper: The controller for path ‘/’ was not found or does not implement IController.
Source Error:

Line 17:     <div id="header">
Line 18: 
Line 19:         @Html.Sitecore().Placeholder("header")
Line 20:     </div>
Line 21:     <div id="content">

Source File:
e:\Local.Sitecore.com\Views\MainLayout.cshtml
Line:
19

[ExceptionWrapper: The controller for path '/' was not found or does not implement IController.]

[ControllerCreationException: Could not create controller: 'TestRenderingController'. 
Remember that the controller name should be specified without the 'Controller' suffix.
The context item is: '/sitecore/content/Home'. 
The current route url is: '{*pathInfo}'. This is the default Sitecore route which is set up in the 'InitializeRoutes' processor of the 'initialize' pipeline. ]
   Sitecore.Mvc.Controllers.SitecoreControllerFactory.CreateController(RequestContext requestContext, String controllerName) +371
   Sitecore.Mvc.Controllers.ControllerRunner.GetController() +24
   Sitecore.Mvc.Controllers.ControllerRunner.Execute() +54

I included a bit of the stack trace for this error as it helps shed some light. The principle route for a Sitecore application is just the path and is corresponding relation to the Sitecore tree. The error message itself gives an impression that the issue is much higher in the render stack than it actually is. But if you look down to the ControllerCreationException then we get at the heart of what’s going on, and that is the controller definition in the rendering doesn’t correspond to a controller the MVC stack can find. One thing to note is much like the the MVC stack scans defined locations for view, it also tracks it’s controllers. As the stack trace indicates, you need to leave off the controller suffix as when you don’t the MVC stack search for a controller named “TestRenderingControllerController”.

The other requisite field is Controller Action field.  The defines what method on the controller to invoke.  The action field needs not necessarily be defined and if no action is defined, the default is the index method.  I won’t go into the errors for missing this field as they are pretty straight forward and descriptive.

Conclusion

Though MVC is very much a different world it still the Sitecore world.  Hopefully this can help get you past some of the initial disconnect.  If any other MVC explorers know of any other common pit traps, post them in the comments below.

Like what you see? Something I missed? Have an even cooler way to do the same thing?!?! Let me know in the comments below.

2 Responses to Intro to Sitecore MVC for the Sitecore Veteran

  1. Andria says:

    Hi Eves,

    I am currently running to the last issue (Controller Rendering).
    I checked the controller name, it’s without ‘Controller’ and the Action name is there as well but I still get this error message.

    Do you have any other idea why is it still happening?

    Thanks

    • Dusty Eves says:

      Hi Rina,

      The most common causes for this error are 1 of 3 things. The first you addressed is the class ending in the word Controller (but with no “Controller” in the rendering definition). The second is most probably a typo of some sort. Keep in mind that the class name are case sensitive, so if you’ve a case-mismatch that could be the source of the problem. The third possible issue is from what class your Controller derives. Inheriting from System.Web.Mvc.Controller is the easiest way through that issue.

      Cheers,

      Dusty Eves

Leave a Reply

Your email address will not be published. Required fields are marked *