In MVC3 Razor, how do I get the html of a rendered view inside an action?

I use a static method in a class I called Utilities.Common I pass views back to the client as properties of JSON objects constantly so I had a need to render them to a string. Here ya go:

public static string RenderPartialViewToString(Controller controller, string viewName, object model)
{
    controller.ViewData.Model = model;
    using (StringWriter sw = new StringWriter())
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.ToString();
    }
}

This will work for full views as well as partial views, just change ViewEngines.Engines.FindPartialView to ViewEngines.Engines.FindView.


The accepted answer by @Chev above is good, but I wanted to render the result of a specific action, not just a particular view.

Also, I needed to be able to pass parameters to that action rather than rely on injecting a model.

So I came up with my own method, that I put in the base class of my controllers (making it available to them all):

    protected string RenderViewResultAsString(ViewResult viewResult)
    {
        using (var stringWriter = new StringWriter())
        {
            this.RenderViewResult(viewResult, stringWriter);

            return stringWriter.ToString();
        }
    }

    protected void RenderViewResult(ViewResult viewResult, TextWriter textWriter)
    {
        var viewEngineResult = this.ViewEngineCollection.FindView(
            this.ControllerContext, 
            viewResult.ViewName, 
            viewResult.MasterName);
        var view = viewEngineResult.View;

        try
        {
            var viewContext = new ViewContext(
                this.ControllerContext, 
                view, 
                this.ViewData, 
                this.TempData, 
                textWriter);

            view.Render(viewContext, textWriter);
        }
        finally
        {
            viewEngineResult.ViewEngine.ReleaseView(this.ControllerContext, view);
        }
    }

Suppose I have an action called Foo that takes a model object and some other parameters, which together influence what view will be used:

    public ViewResult Foo(MyModel model, int bar)
    {
        if (bar == 1)
            return this.View("Bar1");
        else
            return this.View("Bar2", model);
    }

Now, if I want to get the result of calling action Foo, I can simply get the ViewResult by invoking the Foo method, and then call RenderViewResultAsString to get the HTML text:

    var viewResult = this.Foo(model, bar);

    var html = this.RenderViewResultAsString(viewResult);