How to Render Partial View into a String

DaveDev picture DaveDev · Mar 29, 2010 · Viewed 71k times · Source

I have the following code:

public ActionResult SomeAction()
{
    return new JsonpResult
    {
        Data = new { Widget = "some partial html for the widget" }
    };
}

I'd like to modify it so that I could have

public ActionResult SomeAction()
{
    // will render HTML that I can pass to the JSONP result to return.
    var partial = RenderPartial(viewModel); 
    return new JsonpResult
    {
        Data = new { Widget = partial }
    };
}

is this possible? Could somebody explain how?

note, I edited the question before posting the solution.

Answer

Ted Nyberg picture Ted Nyberg · Oct 6, 2013

I opted for an extension method like the following for an ASP.NET MVC 4 app. I think it's simpler than some of the suggestions I've seen:

public static class ViewExtensions
{
    public static string RenderToString(this PartialViewResult partialView)
    {
        var httpContext = HttpContext.Current;

        if (httpContext == null)
        {
            throw new NotSupportedException("An HTTP context is required to render the partial view to a string");
        }

        var controllerName = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString();

        var controller = (ControllerBase)ControllerBuilder.Current.GetControllerFactory().CreateController(httpContext.Request.RequestContext, controllerName);

        var controllerContext = new ControllerContext(httpContext.Request.RequestContext, controller);

        var view = ViewEngines.Engines.FindPartialView(controllerContext, partialView.ViewName).View;

        var sb = new StringBuilder();

        using (var sw = new StringWriter(sb))
        {
            using (var tw = new HtmlTextWriter(sw))
            {
                view.Render(new ViewContext(controllerContext, view, partialView.ViewData, partialView.TempData, tw), tw);
            }
        }

        return sb.ToString();
    }
}

It allows me to do the following:

var html = PartialView("SomeView").RenderToString();

Also, this approach persists any Model, ViewBag and other view data for the view.