Calling MVC Areas From WebForm Pages

No Comments August 5, 2011

I'm currently working on a project that involves moving a large classic ASP.NET WebForms application to ASP.NET MVC3; rather than completing re-implementing the system as MVC3 in one large hit, we're taking a hybrid approach so that existing WebForms content can run alongside the new MVC3 code.

As part of this work, we realised we would need to be able to render content from ASP.NET MVC Areas from within WebForms pages, otherwise there would be a huge duplication of work involved in producing UserControls (or ServerControls) that duplicated the new functionality we are already writing as Areas. So, we started hunting around for a way to achieve this.

After hunting around in MSDN and on StackOverflow, it turns out the solution is moderately easy; the first step is to create a dummy Controller:

public class WebFormController : Controller
{
}

Seriously, that's all there is to it. Next, create a partial view that does nothing but render an Area:

@Html.Action("Index", "Home", new { Area = "HelloWorld" })

Again, stupidly simple. The magic happens here though:

public class WebFormMvcUtil
{
    public static string RenderPartial(string partialName, object model)
    {
        var httpContextWrapper = new HttpContextWrapper(HttpContext.Current);

        var routeData = new RouteData();
        routeData.Values.Add("controller", "WebFormController");

        var controllerContext = new ControllerContext(new RequestContext(httpContextWrapper, routeData),
                                                      new WebFormController());

        IView view = ViewEngines.Engines.FindPartialView(controllerContext, partialName).View;

        ViewContext viewContext;
        var stringBuilder = new StringBuilder();
        using (var stringWriter = new StringWriter(stringBuilder))
        {
            viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary {Model = model}, new TempDataDictionary(), stringWriter);
            view.Render(viewContext, viewContext.Writer);
        }

        return stringBuilder.ToString();
    }
}

With this in place I can now place a

<%= WebFormMvcUtil.RenderPartial("_Area", null) %>

 directive in my WebForms page. So now, I have a mechanism to invoke a PartialView (and therefore, by extension, an Area) from our old codebase. Phew, crisis averted!

 


No Comments