Mark Everard

Hello, I'm Mark – a PhD physicist turned technologist / architect.

Archive for the ‘MVC’ Category

Building a Hybrid MVC / WebForms site with EPiServer CMS6R2

with 4 comments

We have recently delivered an EPiServer CMS6R2 site where some parts of the application were delivered using the ASP.NET MVC framework, and some using the standard WebForm technology. Although this is currently not a supported or recommended way of building an EPiServer site, I thought I’d share some of the solutions we had to put in place to create our monster……..

Hybrid applications

ASP.NET allows you to create hybrid applications that combine all parts of the ASP.NET stack, from WebForms, MVC to Dynamic Data and WCF.  EPiServer itself has been a hybrid application since the release of EPiServer CMS 6. The Dashboard feature and Gadgets use the MVC framework and it is possible to integrate your own MVC plugins.

MVC templates in EPiServer

Despite being a hybrid application, EPiServer 6 does not support delivering CMS managed MVC templates (though EPiServer 7 does have this feature). Joel Abrahamsson went some way to allowing this with his EPiMVC project. Although the project delivered the basic functionality well, it was difficult to implement some of the more advanced EPiServer features, such as XForms.

Why would you do this?

The beauty of the dream vanished, and breathless horror and disgust filled my heart.

Good question. Very good question! Our requirements were to build a community-based application rather than a typical brochure-ware CMS site. There was still need for content managed ‘article’ type pages but the majority of data presented to a user would come from a set of 3rd party SOAP web-services. This data composed only a small part of the wider business domain (which is why we didn’t consider EPiServer Relate as a suitable solution fit).

The community aspects of this project were required to have a ‘modern interface’, i.e. something clean,  accessible and with support for browsers ranging from no javascript to those allowing for partial page updates using AJAX.  This isn’t impossible to achieve with ASP.NET WebForms but it’s architecture increases the complexity significantly. Also – higher complexity means you should consider your UI testing strategy – again something difficult to achieve with WebForms (lookup WebForms MVP if you’re interested in testable WebForms).

Our solution

EPiServer MVC Hybrid Logical separationWell – the title of this piece probably gives this away, but mainly because of the clear separation between the CMS pages and the community application – we decided to build a hybrid, which would utilise EPiServer as the CMS platform to take advantage of it’s multi-lingual / personalisation features, but deliver all of the community based use-cases as MVC views supplemented with EPiServer data.

Largely these two approaches were isolated, however there were some custom pieces we had to extend and override and build to make a coherent whole.

A Route aware UrlRewriteProvider

EPiServer has its own UrlRouting/Rewriting feature that allows friendly extension-less URLs to be resolved to WebForm templates. MVC by default has its own routing system that allows requests to be routed to the correct Controller.

We needed MVC routes to be honoured over EPiServer friendly urls; with the requests that don’t match a route being handled by EPiServer.  This scenario also allows the MVC templates to be viewed in edit mode by creating a simple container at the correct place in the content tree.

Standard MVC applications define a greedy approach to routing requests – that is the RouteTable contains a wildcard approach and would in most cases match. We had to change this implementation so that we defined only the routes that we needed to resolve. Along with this, we created our own implementation of a EPiServer FriendlyUrlRewriter that checked each request to see if it was satisfied by the RouteTable and if so deferred the request to the MVC routing system.

Additionally – we had used the IRouteConstraint interface to allow us to handle EPiServer language segment slugs within the MVC routes. Our custom constraint used the EPiServer LanguageBranch API to ensure that only enabled language slugs were matched by the MVC routing system.

Delivering PageData to the MVC views

EPiServer’s API already provides a rich method for content retrieval. As each of the community MVC pages would only ever have a single instance, passing this data to each controller was relatively straight-forward. We usedthe standard EPiServer pattern of creating a settings-page that defines page references to each page instance we require. This gives simple API access to the correct PageData object.

Reuse of common components

Creating a site using two different display technologies can lead to a duplication of effort when creating consistent/static page elements such as header / footers and navigation. We were keen to avoid this where possible. We used MVC2 and the WebFormViewEngine to create our MVC views. The WebFormViewEngine is built on top of the existing WebForm display technology meaning we could reuse common ASP.NET web controls directly in our MVC views (note this only works for data display – the PostBack mechanism doesn’t work). We also built a mechanism for rendering MVC partial views in a WebForm context following a similar method to this StackOverflow post.

Exposing the EPiServer Resource Provider

We wanted to expose the EPiServer XML resource provider implementation to our MVC views so that we could have a common repository of language resources in use across the site – so we created a few HTML helper methods that allowed us to hook right in.

Should I do this?

This is just a top-level overview of the main pieces we had to think about to use MVC and EPiServer in this way. The take-away point here is to be very sure that there is real value in this approach before building anything like this. For us – it worked (and is still working) really well……………..

Written by mark

October 17th, 2012 at 11:30 am

Posted in ASP.NET,EPiServer,MVC

Creating a custom ModelBinder allowing validation of injected composite models

with 2 comments

Model Binding – is the ‘auto-magic’ step performed by the ASP.NET MVC framework to convert user submitted data (either http post values, querystring values or url route values) into a strongly typed model, used in your controller actions.

Out of the box, the MVC framework also allows you to set validation attributes on your models which are inspected at the model binding stage, meaning that your controller actions can inspect the ModelState.IsValid property to assess whether the user submitted data meet expectations. This attribute based approach to validation provides a clean way to handle validation (a cross-cutting concern) without introducing additional code into your controller action.

One of the features needed when putting together the Fortune Cookie Personalization Engine for EPiServer was to perform validation on a user submitted criteria value. As a reminder, in the context of the Personalization Engine, a criteria is an editor submitted string which is persisted and used by a ContentProvider to allow for a more granular method of content retrieval. For further background and explanation, check out one of my earlier posts – Personalization Engine – ContentProvider Criteria Models

In the full Personalization Engine domain model, criteria properties belong to IContentModel objects which are used to specify the user interface displayed to an editor to allow them to enter the criteria. Below is an example of a TextBoxCriteriaModel which renders as a textbox in the Admin interface.


The string value from this criteria input is posted to the controller action.  However as the type of IContentModel depends on the value of the ContentProvider dropdown, validation attributes cannot be set directly on the model passed to/from this view as different concrete IContentModel types need to be able to specify different validation rules.

To provide validation of the composite IContentModel using validation attributes, we have to hook in to one of the extension points of the ASP.NET MVC framework and create a custom model binder.

Validating composite models

Our custom ModelBinder needs to perform the following tasks:

  • Bind the incoming data against an AdminViewModel (the model passed from the user interface shown above).
  • Obtain an instance of the specified ICriteriaModel and update the ICriteriaModel’s criteria property with the value posted by the form.
  • Validate the composite (and now populated) ICriteriaModel
  • Update the ModelState with the validation results from the composite model, along with the original parent model validation results

As the custom ModelBinder needs to perform all of the existing validation and binding that the DefaultModelBinder would, I’ve chosen to inherit from it and add the additional composite model validation logic into the overriden BindModel method. An instantiated IContentModel is obtained from the AdminViewModel, and the ModelValidator framework class allows us to validate the composite IContentModel, before updating the bindingContext.ModelState with an validation errors.

public class CriteriaValidationModelBinder : DefaultModelBinder
   const string ValidationPropertyName = "Criteria";

   public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
      if (bindingContext.Model != null)
         return bindingContext.Model;

      var model = base.BindModel(controllerContext, bindingContext);

      var adminViewModel = model as AdminViewModel;
      if (adminViewModel == null)
         return model;

      var criteriaValue = bindingContext.ValueProvider.GetValue(ValidationPropertyName);
      adminViewModel.CriteriaModel.Criteria = criteriaValue != null ? criteriaValue.AttemptedValue : string.Empty;

      ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => adminViewModel.CriteriaModel, typeof(ICriteriaModel));
      ModelValidator compositeValidator = ModelValidator.GetModelValidator(modelMetadata, controllerContext);

      foreach (ModelValidationResult result in compositeValidator.Validate(null))
         bindingContext.ModelState.AddModelError(ValidationPropertyName, result.Message);

      return model;

Our custom ModelBinder can be hooked into our application in Global.asax, or in an EPiServer IInitializableModule using the following method.

private void AddCriteriaValidationModelBinder()
    ModelBinders.Binders.Add(typeof(AdminViewModel), new CriteriaValidationModelBinder());

And that’s it…. ModelBinders are an important piece of the MVC framework, and in the majority of scenarios you can rely on the DefaultModeBinder to handle all of your requirements. However creating your own ModelBinder for more advanced requirements is pretty straightforward, depending on your requirements for your binder 🙂

Written by mark

July 18th, 2011 at 10:00 am

Posted in ASP.NET,C#,EPiServer,MVC