Sharing a single _ViewStart across areas in ASP.NET MVC

When using Areas in MVC it’s common to want to use a single layout template for all views. To easily assign a layout template the most common approach is to use a ~/Views/_ViewStart.cshtml (or .vbhtml) in the parent directory of the views. The problem is that when using areas, the ~/Views/_ViewStart.cshtml is not in a parent directory because areas are located in ~/Areas (a sibling of ~/Views). This means the ~/Views/_ViewStart.cshtml is not considered for assigning a default layout template for views within areas.

One commonly suggested solution is to put a _ViewStart.cshtml in the views directory inside each area:

So the obvious approach is to place the _ViewStart.cshtml in the root folder of the entire project. The only problem is that when you create ~/_ViewStart.cshtml and then run the application you end up with this compilation error:

Type ‘ASP._Page__ViewStart_cshtml’ does not inherit from ‘System.Web.WebPages.StartPage’.

In its wonderful eloquence, this is explaining that you’re using a .cshtml file in MVC and not in WebMatrix. The issue here is that Razor is used in two contexts: 1) MVC and 2) WebMatrix.

So our problem is that we need to tell the ASP.NET compiler to compile this in the context of MVC. This is simple – the same razor configuration that was in ~/Views/web.config simply needs to be moved (or copied) out to the top-level ~/web.config (so the <configSections> and the <system.web.webPages.razor> elements):

And that’s it. You can now have a single ~/_ViewStart.cshtml that assigns a default layout template for all your views (both inside and outside areas).

Oh except for one problem. If you create the top-level ~/_ViewStart.cshtml and run the application prior to copying the configuration values in ~/web.config you might still get the same error from before:

Type ‘ASP._Page__ViewStart_cshtml’ does not inherit from ‘System.Web.WebPages.StartPage’.

The issue here is that once the ~/_ViewStart.chtml has been compiled by the ASP.NET runtime the assembly is cached and not re-compiled when the ~/web.config is changed. The simple fix is to make the changes in ~/web.config and then open and save ~/_ViewStart.chtml. Updating the timestamp on ~/_ViewStart.chtml triggers a recompile but now with the updated settings in ~/web.config.

Here’s a sample project that illustrates this working: http://sdrv.ms/PSTHKk

Advertisements

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