Category Archives: Webforms

Using MVC RenderAction within a Webform

As pointed out in the previous post (<here>) it is possible to call the MVC RenderPartial from within a webform.  This assumes that your webform has all the information it needs to populate the required model.  Where this information is not available, a good alternative is to use RenderAction from within the webform:

Add the following to the MvcUtility class described in the previous post:

public static void RenderAction(string controllerName, string actionName, object routeValues)
   RenderPartial("RenderAction", new RenderActionViewModel() { ControllerName = controllerName, ActionName = actionName, RouteValues = routeValues });

Create the viewModel to support the data we want to pass:

public class RenderActionViewModel
   public string ControllerName { get; set; }
   public string ActionName { get; set; }
   public object RouteValues { get; set; }

And, create a partial view to make the RenderAction request (I put mine in the Shared directory)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RenderActionViewModel>" %>
<%Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues); %>

Then, all that is needed is to call the MvcUtility.RenderAction from within a webform, passing it the name of the controller, action and and additional parameters that your action method requires.  Examples:

<% PartialViewHelper.RenderAction("myController", "myAction", new { param = Value }); %>
<% PartialViewHelper.RenderAction("Blogs", "List", new { page = 1, order = "date", comments = "off" }); %>

This is a great way of adding MVC functionality to a Webforms environment.


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(&quot;controller&quot;, 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)
      throw new InvalidOperationException(String.Format(&quot;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… Continue reading

Am I in an MVC or Webforms environment?

I’m currently working on an interesting project which is a combination of legacy code built using webforms, as well as a whole bunch of new functionality developed using MVC.  Due to the sheer volume of code and functionality within the existing system there is simply no possibility of rewriting all the existing forms and underlying code to use the MVC, however we are using MVC wherever possible to build new functionality and extend the system.

This leads to some interesting challenges, in particular within shared areas of code that need to work differently when the user is within a webforms part of the solution, compared to when the user is in a MVC based page.

It was therefore necessary to try and figure out if a particular web request cycle is part of MVC or not.  Rather than write some complex set of routines (and I tried to develop a few) I came up with a remarkably simple mechanism – ‘ask’ the MVC routing engine whether it is able to route the current web request.  If it can route the request to an MVC controller then MVC is being used, otherwise we can assume that its a webforms request.

// To determine if its an MVC Request, look at for a 'controller' value in the route data for this request
public bool IsMvcRequest(HttpContext context)
RouteData routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(context));
if (routeData != null &amp;amp;&amp;amp; routeData.Values["Controller"] != null)
return true;
return false;

The reason that this works within the webforms environment, is that the Routes class is created as public within the global.asax which is executed for all requests, not just mvc.