CMS Friendly URL With MVC (Simple)
I currently working on HUGE MVC project for a customer through Pentia. They are rebuilding their entire website from .Net webforms to MVC 3 with Razer.
So one of the first task was to build som simpel functionality tha could resolve their url delivered from the underlying CMS.Instead of register specific routes for the different pagetypes in the CMS
I came up with this solution shown in this blogpost.
To begin with I registered a new “CMS route in global.asax”. All URL shoul hit this route, ofcourse you could make other routes before this.
//RouteMap for CMS content routes.MapRoute("CMSRoute", "{*url*}").RouteHandler = new CmsRouteHandler();
Now to the simple CmsRouteHandler implementation it simply calls the CmsHttpHandler a relying on the handler to find a correct controller to desplaying the current request.
public class CmsRouteHandler : IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { return new CmsHttpHandler(requestContext); } }
Now the CMSHttpHandle which for this blogpost is simplyfied to always returning the
frontpage. This should offcourse by matching the url to a page i DB and displaying the
and resolve it to the correct controller.
public class CmsHttpHandler : IHttpHandler { private RequestContext RequestContext { get; set; } private IControllerFactory ControllerFactory { get; set; } private IController Controller { get; set; } public CmsHttpHandler(RequestContext requestContext) { RequestContext = requestContext; } public void ProcessRequest(HttpContext context) { HttpContext = context; InstantiateControllerFactory(); InstantiateController(); SetupRequestContext(); Controller.Execute(RequestContext); } private HttpContext HttpContext { get; set; } private void InstantiateControllerFactory() { ControllerFactory = ControllerBuilder.Current.GetControllerFactory(); } private void InstantiateController() { Controller = ControllerFactory.CreateController(RequestContext, Pagetype); } private void SetupRequestContext() { RequestContext.RouteData.Values.Add("controller", Pagetype); //Always render Index action, all pagetype controllers must implement Index action RequestContext.RouteData.Values.Add("action", "Index"); AppendQueryStrings(); } private void AppendQueryStrings() { foreach (string name in HttpContext.Request.QueryString) RequestContext.RouteData.Values.Add(name, HttpContext.Request.QueryString[name]); } private static string ResolvePagetypeFromUrl() { //Should return apgetype from db/URL return Pagetype } private string _pageType; private string Pagetype { get { //Resolve pagetype from DB fx //For now we will just return the frontpage /return string should match controller name return "frontpage"; } } public bool IsReusable { get { throw new NotImplementedException(); } } }
Hope you find it usefull..