Sunday, September 27, 2009

Step by step Migrating and mixing ASP.NET Web Forms to ASP.NET MVC

We have a big product on classic ASP.NET Web Forms. It really big therefore is not possibly to rewrite it on MVC for time

We wish to write a new code on ASP.NET MVC, step-by-step copying old as far as possible. But application is very separated into small components. And from one side we cannot create new ASP.NET MVC page without possibility to use old components from MVC views. And cannot create new MVC parts/components without possibility to render it on old Web Forms pages.

I’m not sure that it is a good idea to use Web Forms components from MVC views, because many concepts form Web Forms simply not works in MVC, and many code should be rewritten ( such as event handlers, something stored in ViewState etc. ). In this case seems that more reasonable rewrite Web Forms Components at all.
But what about backward Interop? Seems that it can be reasonable if you want to write new parts on MVC. we simple need somehow create Html and Url helpers similar to MVC helper and call methods such as Html.RenderAction and Url.Action
Here is snippet that create such helpers, that can be used from classic ASP.NET Web Forms:
public static class ControllerExtensions
{
public static HtmlHelper CreateHtmlHelper( this HttpContext context )
{
var request_context = new RequestContext( new HttpContextWrapper( context), new RouteData() );
var controller_context = new ControllerContext( request_context, new StubController );
var dictionary = new ViewDataDictionary();
var wrapper = new ViewWrapper( dictionary );
var viewContext = new ViewContext( controller_context, wrapper, dictionary, new TempDataDictionary() );
return new HtmlHelper( viewContext, wrapper );
}
public static UrlHelper CreateUrlHelper( this HttpContext context )
{
return new UrlHelper( new RequestContext( new HttpContextWrapper( context ), new RouteData() ) );
}
}
internal class StubController : Controller
{
}
internal class ViewWrapper : IView, IViewDataContainer
{
public ViewWrapper( ViewDataDictionary dictionary )
{
ViewData = dictionary;
}
#region IView Members
public void Render( ViewContext viewContext, TextWriter writer )
{
}
#endregion
#region IViewDataContainer Members
public ViewDataDictionary ViewData { get; set; }
#endregion
}


Usage:


//This can be placed in BasePage class to possible to use on all your pages.protected HtmlHelper Html;
public void OnLoad(...)
{
Html =HttpContext.Current.CreateHtmlHelper();
} 


<% Html.RenderAction<SomeController>( c =>c.some_action( some, params ) ); %>

So this way you can Mixing ASP.NET Webforms and ASP.NET MVC Views in your project.

1 comment: