Wednesday, 15 May 2013

Render partial view into string in controller



I have run into a situation where I would like to render a partial view to a string and then return it as part of a JSON response like so:

return Json(new {
 personHtml = RenderPartialViewToString("Person", person)
});
The ability to do something like this would open up a ton of amazing possibilities, so I really scoured the internet looking for a solution. Unfortunately, no one seems to have come up with a clean solution for it, so I dug into the MVC code and came up one…and because I’m such a nice guy, you get to copy it for free. ;)


public abstract class MyBaseController : Controller {

    protected string RenderPartialViewToString()
    {
        return RenderPartialViewToString(null, null);
    }

    protected string RenderPartialViewToString(string viewName)
    {
        return RenderPartialViewToString(viewName, null);
    }

    protected string RenderPartialViewToString(object model)
    {
        return RenderPartialViewToString(null, model);
    }

    protected string RenderPartialViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = ControllerContext.RouteData.GetRequiredString("action");

        ViewData.Model = model;

        using (StringWriter sw = new StringWriter()) {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
}

Now you can simply do this:

public class MyController : MyBaseController {

    public ActionResult CreatePerson(Person p) {     
            return Json(new {
                    statusCode = 1,
                    statusMessage = "The person has been added!",
                    personHtml = RenderPartialViewToString("Person", p)
                });
    }
}
Also note that you can modify these functions to render a View (rather than a PartialView) with this small change:

ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName);
Enjoy!

My final implementation is:

  /// <summary>
        /// Renders the partial view to string.
        /// </summary>
        /// <param name="viewName">Name of the view.</param>
        /// <param name="model">The model.</param>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="viewData">The view data.</param>
        /// <param name="tempData">The temp data.</param>
        /// <returns>Returns parsed view as string.</returns>
        /// <remarks>
        /// Used from page: http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/
        /// </remarks>
        public static string RenderPartialViewToString(string viewName, object model, ControllerContext controllerContext, ViewDataDictionary viewData, TempDataDictionary tempData)
        {
            viewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName);
                ViewContext viewContext = new ViewContext(controllerContext, viewResult.View, viewData, tempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        } 
My code is based on :
http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string