Mixing ASP.NET WebForms with MVC
Posted 01 Feb 2009
MVC offers a lot of nice features but switching from regular ASP.NET webforms to MVC on exisiting projects is not easy. Out of the box, MVC is very rigid about where you place your views (.aspx). There is little support for user controls and no support at all for custom controls. This makes mixing webforms with MVC next to impossible without breaking existing functionality.
With a couple of additions to MVC though you're pretty much free to do what you want. The functionality introduced in this post enables mixing of MVC and WebForms pages. You can reuse exisiting controls, both user controls and custom controls. You can even go as far as rendering pages from just a master page and controls.
This post will show you how to compose pages from controls using the same mechanisms ASP.NET uses when rendering regular pages from .aspx files. First we'll look at the way master pages and regular .aspx pages interact and then I'll show you how to uses this interaction to do the same from an MVC controller. For some background information the internals of pages you may also want to check an earlier post on the subject.
Master pages in a nutshell
Master pages in ASP.NET use content placeholders to indicate where the page may be customized. Normally, each page (.aspx) declares content within one or more content controls. At runtime (or when precompiling) ASP.NET will generate code that registers the contents with each template container. When the page is being processed during a web request, it instantiates the contents of each of the content controls in the templates available from the master page. The key method is in the Page.AddContentTemplate( string name, ITemplate template ) method. In pages compiled from an .aspx file this method will be invoked while building the page control structure. This is done from an override of the Page.FrameworkInitialize method, containing most of the generated code for the page. We can use that to hook up whatever content we want to render in a master page.
Implementation
The code below shows a ViewPage that supports this mechanism:
This class enables us to setup a template for each content placeholder in a master page. The Template class is a straight up implementation of the ITemplate interface that supports multiple controls to be added as either a virtual path or a control instance.
With these classes we have the plumming setup to render a page using a master page and inject any control we want into that. Next, this needs to be hooked up to MVC. The way to do this is create a custom ActionResult.
This class provides a controller with the means to create a view and execute it. For a simple HelloWorld example the controller would look like this:
This would require a master page named materpage.master with at least one content placeholder named Body.
Real world applications
For real world applications you'd probably declare extension methods for Controller that setup the MasterPageFile and Theme as used by the site. I've found that these classes make it much easier to migrate from pure webforms to MVC. It allows you to use MVC for new developments while enabling reuse of existing controls.
[Update: 1 May 2009]
Source code is now available for download. Please read my post on Alanta.Mvc.
Marnix
Hi,
Thanks for the tip.
The article you're referring to is not quite the same thing; it describes how webforms and MVC can co-exist using routing. The solution I'm proposing here allows you to mix assets from WebForms based applications with MVC; it enables you to use MVC controllers with webforms controls in ways not supported by MVC itself.
This solution enables the controller to dictate which partial views (or controls) are to be loaded into what content template in a master page. This is a different way of constructing views compared to MVC's hierarchical views.
I'm using this solution for new developments on existing sites. It allows me to reuse existing controls developed for webforms-based pages while developing new functionality using MVC.
Unknown
Have a look at this. It would seem you don't have to go to the trouble of what your describing....
http://www.packtpub.com/article/mixing-asp.net-webforms-and-asp.net-mvc