Rendering an ASP.NET MVC View to a string in a Web Api Controller

2012-10-12    

Today I was working on a Web Api Controller that integrated with a third party application. The application wants us to return an XML document. One of the nodes is a piece of HTML that is displayed in the application.

So I started thinking about a flexible way to render HTML from a WebApi Controller. After searching around on the web I came up with a solution.

Sneaking my way into MVC

The biggest problem was that rendering a View is something that normally shouldn't happen inside Web Api. The solutions I found on the web all use some kind of MediaTypeFormatter to return HTML when the client requests it.

However, that's not what I want. I want to return the following data to the client where the Body property should contain an HTML string:

public class ContentItem
{
    public string Title { get; set; }
    public string Body { get; set; }
    public string Widgets { get; set; }
}

Eventually this is what I came up with:

public static string RenderViewToString(string controllerName,
                                       string viewName,
                                       object viewData)
{
   var context = HttpContext.Current;
   var contextBase = new HttpContextWrapper(context);
   var routeData = new RouteData();
   routeData.Values.Add("controller", controllerName);

   var controllerContext = new ControllerContext(contextBase,  
                                                routeData,
                                                new EmptyController());

   var razorViewEngine = new RazorViewEngine();
   var razorViewResult = razorViewEngine.FindView(controllerContext,
                                                   viewName,
                                                   "",
                                                   false);

   var writer = new StringWriter();
   var viewContext = new ViewContext(controllerContext,
                                    razorViewResult.View,
                                    new ViewDataDictionary(viewData),
                                    new TempDataDictionary(),
                                    writer);
   razorViewResult.View.Render(viewContext, writer);

   return writer.ToString();
}

  class EmptyController : ControllerBase
  {
      protected override void ExecuteCore() { }
  }

You can simply call this from anywhere in your Web Api Controller:

RenderViewToString("controller", "view", model)

Have you run into similar issues? Can you use this code or do you have another idea? Please leave a comment!