I have been playing with the new ASP.Net MVC Framework that is part of the ASP.NET 3.5 Extensions CTP release. I really like how simplified the MVC Framework has made things. One thing I wanted to try out is how would you leverage master pages for things that needed to be rendered on every page. Something like a product category for an online store that only shows products that are in a given category when the user clicks on the desired category. I wanted to be able to place this category list on the master page so it could be maintained in one place. This blog post explains how I managed to accomplish this.
First make sure you download the ASP.NET 3.5 Extensions Preview and also the MVC Toolkit. This example uses the Northwind database. There are many other blog posts that explain how to create the MVC Solution so I will not go through those details here. Basically I created an MVC Web Application and a separate Class library to hold the data model. In the model I only added the following tables from the Northwind database: Categories, Orders, Order Details, Customers and Products. I also made sure I had the MVCToolkit.dll referenced in my web project so I could use some of the advanced Html Helper classes.
In the web application project under the Models folder create a new class called DefaultDataView and add a property that can hold a list of Categories. This class will be the default strongly typed data container that all other data containers will be derived from.
Create another data container class and call it ProductDataView in the Model folder of the web project. This class will derive from the DefaultDataView. Add a property to the class to hold a list of products.
Create a public partial NorthwindDataContext class in the model project and add a method to return the categories as a list.
Create a ProductController class to handle displaying the list of filtered products based on a passed in category id. Notice how I am using the subclass ProductDataView to hold the list of categories as well as the filtered list of products.
Now lets get the master page to display a list of product categories. Add a new div tag above the maincontent div tag in the Site.Master page. The logic just iterates over the list of categories emitting a link to the products list action. Notice the use of the ActionLink method on the Html helper class. Since the List Action on our Product Controller accepts a category Id as a parameter I can just append the category Id to the end of List and the parameter will be injected into the controller List method.
Create a view to display the list the products.
I also modified the Index and About methods on the HomeController to use the strongly typed data container and load the categories. Since neither of these actions load any other view specific data I used the DefaultDataView as the object to transport data to the view for rendering.
The end result when a user clicks on one of the categories is as follows.
As you can see it is very easy to split out common rendering logic into a master page even in the MVC Framework. I used strongly typed data container objects as a way to send data to the view but I could have used the un-typed method just as easily. I generally like to stay strongly typed as much as possible though. I want compile time checks for heavy refactorying while developing in an agile environment.
Another interesting concept here was that I was able to stay away from using any code behind logic or server controls. It is a big debate these days on if code behind should be used or not. If you don't use code behind you will end up with some C# code mixed in with HTML which I am not convinced is good or bad. In a lot of ways I think mixing HTML and C# makes the code hard to read. I guess I have to try it for a while before I decide one way or the other. The VS 2008 Intellisense support and the MVC Html helper class is what will make a mixed HTML and C# solution a success.
All in all I really like the MVC Framework and I think it will be a great tool for building complex and maintainable web applications. I am certainly going to use this framework on future projects and I am looking forward to it's production release.
Here is the solution if you want to download it.