Using MVC RenderPartial within a webform

I you are lucky, like me, you get to work on both MVC and Webforms projects, often simultaneously, in mixed environment projects.

One question that commonly arises – how to render an MVC partial view within a webform.  A little study of the MVC source code, and it reveals that its relatively easy, as long as you are able to fake the necessary context elements.

Step 1. Create a dummy controller from which we can create the controller context.  This is simply an empty class that inherits from Controller.

// create a dummy controller
public class DummyController : Controller
{
}

Step 2. Create a static class MvcUtility that constructs the context and call the render method.

public static class MvcUtility
{
   public static void RenderPartial(string partialViewName, object model)
   {
      // Get the HttpContext
      HttpContextBase httpContextBase = new HttpContextWrapper(HttpContext.Current);
      // Build the route data, pointing to the dummy controller
      RouteData routeData = new RouteData();
      routeData.Values.Add("controller", typeof(DummyController).Name);
      // Create the controller context
      ControllerContext controllerContext = new ControllerContext(new RequestContext(httpContextBase, routeData), new DummyController());
      // Find the partial view
      IView view = FindPartialView(controllerContext, partialViewName);
      // create the view context and pass in the model
      ViewContext viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary { Model = model }, new TempDataDictionary(), httpContextBase.Response.Output);
      // finally, render the view
      view.Render(viewContext, httpContextBase.Response.Output);
   }

   private static IView FindPartialView(ControllerContext controllerContext, string partialViewName)
   {
      // try to find the partial view
      ViewEngineResult result = ViewEngines.Engines.FindPartialView(controllerContext, partialViewName);
      if (result.View != null)
      {
         return result.View;
      }
      // wasn't found - construct error message
      StringBuilder locationsText = new StringBuilder();
      foreach (string location in result.SearchedLocations)
      {
         locationsText.AppendLine();
         locationsText.Append(location);
      }
      throw new InvalidOperationException(String.Format("Partial view {0} not found. Locations Searched: {1},  partialViewName, locationsText));
   }
}

This creates the necessary environment – creating the HttpContext, route data, controller context, finds the view and renders it.  The second routine, FindPartialView uses the ViewEngines to find the partial view and throws an appropriate exception if it can’t find the requested partial.

Finally, within my webform, I create a public property called Model in the code behind and include the following:

<% MvcUtility.RenderPartial("TestPartial", Model); %>

Thats all there is to it…

There is only on drawback to this approach, your code behind needs to populate the model and therefore needs all the model creation information in order to call this.  The next post Using MVC RenderAction within a Webform addresses this…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s