Wednesday, December 21, 2011

ASP.NET MVC and SharePoint 2010

I work with SharePoint every day, but at the same time I really like ASP.NET MVC. Unfortunately these two technologies are not meant to be together, but considering that they are both a part of ASP.NET platform I tried to make them friends. The latest version of ASP.NET MVC that is written in .NET3.5 is version 2.0, so we have to stick with this version in SharePoint 2010 as well. There are already some approaches over the internet that allow to host ASP.NET MVC content in SharePoint.

For example http://sharepointmvc.codeplex.com/.
This solution works fine, but I don't like the idea of using /_layouts/ urls. I tried something different to achieve MVC integration in SharePoint and got the following.

1. Separate feature that deploys custom http handler to SharePoint filesystem.
2. Urls are more friendly (like http://myserver/sites/mvcsite/app.ashx/about).
3. Every subsite might have it's own MVC site and completely independent from each other.
4. Really simple configuration.

So what was done.

I created a small library where I used the concept of MVC areas - every MVC application inside of SharePoint must be an MVC area to have its own routes, controllers, etc. Every MVC application should have its own HTTP handler to distinguish MVC content from SharePoint content. This http handler should be configured correctly to server content from specific area. Here is a sample.


App.ashx - is our MVC http handler.
Layouts\MvcApp - store our MVC views, scripts, stylesheets and all other stuff for standard MVC application.
Web\Controllers - that's clear - MVC controllers.
Web\AppMvcRegistration.cs - MVC area registration class.

In order to configure everything correctly for MVC are it's necessary to write implementation of ISPMvcAreaRegistration interface in our application.

using SPMvc.Core;

namespace SPMvcSample.Web
{
    public class AppMvcRegistration : ISPMvcAreaRegistration
    {
        public string AreaName
        {
            get { return "mvcapp"; }
        }

        public void RegisterRoutes(SPMvcAreaRegistrationContext context)
        {
            context.MapRoute("Home", "app.ashx/home", new { controller = "Home", action = "Index" });
            context.MapRoute("About", "app.ashx/about", new { controller = "Home", action = "About" });
        }
    }
}


There are just two things to implement:

AreaName - very important - it's not just the name of area, but the folder in Layouts directory where all MVC Views should be located for particular application.
RegisterRoutes method - routes registration. During route registration the url of current subsite will be concatinated with http handler url.

This is pretty much all configuration needed to run MVC application in SharePoint.

Very familiar screenshot, isn't it (except it's running in SharePoint)? Notice the url is /sites/mvcapp/app.ashx/home.

The source code of SPMvc solution with some documentation is located here:

https://github.com/vadimi/SharePoint-Mvc

It's possible to deploy this solution not just in GAC, but in medium trust as well (Bin deployment). More details are here:

https://github.com/vadimi/SharePoint-Mvc/wiki/SharePoint-Mvc-and-'Bin'-deployment