Friday, May 1, 2009

Alanta.Mvc : Multiple partial views without .aspx files

In my previous post I've discussed some additions to ASP.NET MVC that I've been using for some time now. I created these additions to enable me to use MVC on existing projects.

What's wrong with MVC? 
The best practices and patterns used by MVC are good but they come at a price. I feel that MVC is not flexible enough to fit in with my preferred way of building sites. Specifically:
  1. The default view engine requires files to be in predefined places, making it difficult to migrate existing ASP.NET sites to MVC without rebuilding the whole application.
  2. The default view engine uses hierarchical view composition. That's nice but not flexible enough; I want the controller to decide what view(s) to render and I want to be able to use multiple partial views on one page.
  3. MVC uses very loose binding. I prefer strong typed binding.

I've addressed the third point in an earlier post, so I won't go into that here.

The first point, about the folder layout of MVC projects, is a matter of taste. I have my reasons for not wanting to conform to the default layout. Mostly because I don't want to rebuild an application just to be able to use MVC for some new functions I'm adding. In addition to this, I find that MVC is very much centered on physical files to represent views.
In many cases I'll build a view from controls already available or by generating HTML in a helper method. Using files (aspx or ascx) to hook all this up adds a layer of complexity I don't need and certainly don't want to maintain. It would be much easier to let the controller handle this.
This brings me to the second reason from the list above. I want the controller to be able to dictate the views that need to be rendered, I do not want to delegate this to an aspx for every conceivable view.

Pros and Cons
In my previous post I've introduced a technique that solves both the first and second issue. In combination with the strong typed routing solution described in another blog post this yields a very usable variation of MVC. In short, the solution I'm offering here has the following benefits:

  • Compose views using master pages, controls and view controls (no .aspx required).
  • Load (partial) views by type (custom controls) or virtual path (user controls).
  • No strict requirements on site structure.
  • Strong-typed routing for controllers.
  • Use MVC with any ASP.NET 3.5 website.

As always, there are some downsides as well:

  • Not using an .aspx file for a view means no visual designer support for views.
  • Most of the nice Visual Studio productivity features for MVC no longer work.

Open source on GitHub
I've made the sources available through GitHub under a BSD license. I will provide best-effort support through GitHub's issue tracking. The sources include a sample website, so check it out if you're interested.
Version is an exact copy of production code I've been using for a couple of months now so it should be stable.



Karel Frajták said...

Hello, I tried your code and it looks good. But there's still viewstate hidden field in generated HTML and that is not desired in ASP.NET MVC web. I tried to disable viewstate in web.config globally and on the page itselt, but that doesn't work.
When I removed all the controls from then homecontroller index action, the viewstate field was still there.
Can you find out where to switch it and update your project?
Thanks a lot

Marnix said...

Hi Karel,

Thanks for your feedback. The ViewState field is generated by the webform in Default.master in the sample application.
If you don't want to support ASP.NET controls, remove the form from the master page.