MVC Areas in Sitecore


Areas have been a part of ASP.NET MVC since ASP.NET MVC 2 shipped in 2010. This walkthrough article from MSDN sums up why areas are useful in MVC web applications. A brief extract follows:

To accommodate large projects, ASP.NET MVC lets you partition Web applications into smaller units that are referred to as areas. Areas provide a way to separate a large MVC Web application into smaller functional groupings. An area is effectively an MVC structure inside an application. An application could contain several MVC structures (areas).

For example, a single large e-commerce application might be divided into areas that represent the storefront, product reviews, user account administration, and the purchasing system. Each area represents a separate function of the overall application.

The release of Sitecore 6.6 saw the introduction of support for MVC and the Razor view engine within the Sitecore CMS. It wasn’t long before a question popped up on stackoverflow asking how to wire up a Sitecore Controller Rendering to a controller located within a MVC Area.

Hopefully this article will provide some answers for those wanting to use MVC Areas with Sitecore and highlight a few of the subtleties that currently may not be so well documented.

Doing the Simplest Thing

In order to demonstrate how to get started with Sitecore and MVC Areas we will first need to create an Area within our Visual Studio development web project. Rather than explain in detail how to do this here I’ll refer you instead to this excellent post on [ASP.NET MVC] Routing – Areas.

Single Area

Single Area within Web Project

The screenshot shows a single area, MyArea, within a development web project. The area itself has a single controller named SimpleAreaController containing the Index method shown in the following code listing.

using System.Web.Mvc;

using Sitecore.Mvc.Controllers;

namespace Cms.Website.Areas.MyArea.Controllers
{
    public class SimpleAreaController : SitecoreController
    {
        public override ActionResult Index()
        {
            return Content("<div>Content from SimpleAreaController</div>");
        }
    }
}

In Sitecore create a new Controller Rendering item based on the /sitecore/templates/System/Layout/Renderings/Controller rendering template. You’ll need to specify the Controller and Controller Action field values. The controller field value in this simple case can be specified using the same convention-over-configuration naming that ASP.NET MVC employs, that is use the controller class name minus the Controller suffix. The controller action field is used to specify which method on the controller to invoke.

one-area-controller-rendering

Now add the rendering to an Item’s presentation details and then preview the Item to verify that content generated by the controller method is getting displayed on the page.

So this is the simplest thing to get started with Controller Renderings and Areas. The fact that you are targeting a controller located within an Area has had no impact on how the field values for the controller rendering are specified and would be the same if the controller was located outside of an Area.

Time to Add a View

Having a controller action method return simple strings to the browser using the Content method is not a very realistic example. A more common scenario is where the action method performs some processing and on completion passes a data object to a View for rendering. This behaviour is shown in the following example.

using System;
using System.Web.Mvc;

using Sitecore.Mvc.Controllers;

namespace Cms.Website.Areas.MyArea.Controllers
{
    public class SimpleAreaController : SitecoreController
    {
        public override ActionResult Index()
        {
            var data = new {Timestamp = DateTime.Now};
            return View(data);
        }
    }
}

The Index.cshtml view file simply writes some different HTML content along with the model value passed to it by the controller action method.

@model dynamic

<div>
    <p>Content from MyArea Simple Area controller via a view</p>
    <p>Model contains - @Model</p>
</div>

If you go ahead and try this out by updating the code within your action method you are likely to run into the first gotcha.

The view 'Index' or its master was not found

As of Sitecore CMS 6.6.0 rev.121203 (Update-2) there is a known issue with locating view files invoked from a controller within an MVC Area. The workaround to this problem is to simply specify the path to the razor view when calling the Controller.View method.

For example:

using System;
using System.Web.Mvc;

using Sitecore.Mvc.Controllers;

namespace Cms.Website.Areas.MyArea.Controllers
{
    public class SimpleAreaController : SitecoreController
    {
        public override ActionResult Index()
        {
            var data = new {Timestamp = DateTime.Now};
            return View("~/Areas/MyArea/Views/SimpleArea/Index.cshtml", data);
        }
    }
}

After specifying the path to the view the server error no longer occurs and the output from the razor view is sent to the browser.

More to come …

This post has hopefully shown you enough to get started on using MVC Areas with Sitecore 6.6. More guidance on topics such as avoiding name collisions when using multiple MVC Areas will be covered in the next part of this article which I hope to post shortly.

Please feel free to leave feedback on this post or provide suggestions for any other Sitecore MVC topics that you would like investigating.

Advertisements

8 thoughts on “MVC Areas in Sitecore

  1. You can use a fully qualified path to you your controller. That helps to allow duplicate controllers and actions in different areas. Sample : “Sample.Areas.SampleArea.Controllers.AccountController,Sample”

    The real solution would be add a new rendering type with third field called “Area” and add it to the route values colleciton when executing the controller. I did this before in the early builds but it changed so much it would take some time to recode this.

  2. Pingback: Sitecore MVC Area Controller Rendering Type « Web Content Management and Delivery

  3. Pingback: Use the Fully Qualified Name When Using a Sitecore MVC Controller – Sitecore Best Practice | XCentium

  4. I improvised it further avoiding need of hard coded view path, I posted a solution here – http://stackoverflow.com/questions/24186018/sitecore-multisite-mvc-solution/24852298#24852298

    Got it further improved with adding namespace in route data and let MVC decide the view path and controller resolution with IDependencyResolver

    http://cprakash.com/2014/10/27/sitecore-and-mvc-areas-as-pluggable-module/

    Added more support to load MVC Areas from multiple MVC project, MVC Form POST and some more in cooking.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s