Two weeks ago we shipped the ASP.NET MVC 3 Beta Release. It supports “go live” deployments, and includes a bunch of nice improvements/enhancements. You can see a summary of the new ASP.NET MVC 3 features in mybeta announcement post. Also read my original ASP.NET MVC 3 Preview post to learn about other ASP.NET MVC 3 features that showed up with that initial preview release.
This is another in a series of “mini-posts” I’m doing that talk about a few of the new ASP.NET MVC 3 Beta features in more detail:
- New @model keyword in Razor (Oct 22nd)
- Layouts (this post)
In today’s post I’m going to discuss layout pages with Razor, and discuss some of the improvements to them that we introduced with the recent ASP.NET MVC 3 Beta.
Razor Basics
ASP.NET MVC 3 ships with a new view-engine option called “Razor” (in addition to continuing to support/enhance the existing .aspx view engine).
You can learn more about Razor, why we are introducing it, and the syntax it supports from myIntroducing Razor blog post. If you haven’t read that post yet, take a few minutes and read it now (since the rest of this post will assume you have read it). Once you’ve read theIntroducing Razor post, also read my ASP.NET MVC 3 Preview post and look over the ASP.NET MVC 3 Razor sample I included in it.
What are Layouts?
You typically want to maintain a consistent look and feel across all of the pages within your web-site/application. ASP.NET 2.0 introduced the concept of “master pages” which helps enable this when using .aspx based pages or templates. Razor also supports this concept with a feature called “layouts” – which allow you to define a common site template, and then inherit its look and feel across all the views/pages on your site.
Using Layouts with Razor
In my last blog post I walked through a simple example of how to implement a /Products URL that renders a list of product categories:
Below is a simple ProductsController implementation that implements the /Products URL above. It retrieves a list of product categories from a database, and then passes them off to a view file to render an appropriate HTML response back to the browser:
Here is what the Index.cshtml view file (implemented using Razor) looks like:
The above view file does not yet use a layout page – which means that as we add additional URLs and pages to the site we’ll end up duplicating our core site layout in multiple places. Using a layout will allow us to avoid this duplication and make it much easier to manage our site design going forward. Let’s update our sample to use one now.
Refactoring to use a Layout
Razor makes it really easy to start from an existing page and refactor it to use a layout. Let’s do that with our simple sample above. Our first step will be to add a “SiteLayout.cshtml” file to our project under the \Views\Shared folder of our project (which is the default place where common view files/templates go):
SiteLayout.cshtml
We’ll use the SiteLayout.cshtml file to define the common content of our site. Below is an example of what it might look like:
A couple of things to note with the above file:
- It is no longer necessary (as of the ASP.NET MVC 3 Beta) to have an @inherits directive at the top of the file. You can optionally still have one if you want (for example: if you want a custom base class), but it isn’t required. This helps keep the file nice and clean. It also makes it easier to have designers and non-developers work on the file and not get confused about concepts they don’t understa