OdeToCode IC Logo

Razor Tip #2 : Inheritance & Configuration

Thursday, January 13, 2011

You can change the base class of a Razor view in ASP.NET MVC using an @inherits directive.

@inherits MyWebViewPage<dynamic>

The  default base class for a Razor view in ASP.NET MVC is WebViewPage<T>, and in most cases you don't need to fiddle with @inherits  - it's more common to use the @model directive and just strongly type the default base class with a specific ViewModel type.

But, when you really need to set a different base class for a view, you'll probably need to set the same base class everywhere. This is where configuration comes into play.

Razor Configuration

In the ~/Views folder, you'll find a web.config with the following section inside.

  <host factoryType="MvcWebRazorHostFactory ..."/>
  <pages pageBaseType="WebViewPage">
      <add namespace="System.Web.Mvc" />
      <add namespace="System.Web.Mvc.Ajax" />
      <add namespace="System.Web.Mvc.Html" />
      <add namespace="System.Web.Routing" />

The razor configuration allows you to include additional default namespaces for view compilation, as well as set the pageBaseType attribute, which will change the base class for all the razor views in an application.

<pages pageBaseType="Infrastructure.MyWebViewPage">

Note the base type must be a generic type, but you don't need to specify the type parameters in the pageBaseType attribute. The MVC framework doesn't appear to interpret this value, but instead copies the value verbatim into the generated code for the view and appends a generic type parameter (<dynamic> by default). For the value specified above, the base class would look like the following:

public abstract class MyWebViewPage<T> : WebViewPage<T>

Generated PictureDo You Need A Base Class?

Remember, views are simple and singularly focused on rendering a model. If you think you need a base class to add logging, business calculations, or other services along those line, then take a step back. There are plenty of opportunities to perform work during execution of the controller action, in an action filter, or in the model itself. Keep your views simple!

If you do use a base class, remember you have the opportunity to inject dependencies into properties with MVC3.

public abstract class MyWebViewPage<T> : WebViewPage<T>
    public ILocalizationHelper Localizer { get; set; }

To pull this off, all you need is a dependency resolver and an inversion of control container that supports property injection. See Brad Wilson's series of posts for some details.