Rendering a view or a partial to a string is a common problem, especially when you want to re-use your code and markup in a PDF or Email. There are a number of semi-successful methods for achieving this across the internet. The techniques outlined below are built on the excellent post from Kevin Craft at http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/ this has the advantage of being simple, straight forward and fully support embedded Html helpers.
Render Partial To String & Render Form To String
Define the following within a Controller base class:
public class BaseController : Controller
{
protected string RenderPartialToString(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);
validateViewResult(viewResult, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
protected string RenderViewToString(string viewName, object model, string masterName)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, masterName);
validateViewResult(viewResult, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
private static void validateViewResult(ViewEngineResult viewResult, string viewName)
{
if (viewResult.View != null)
return;
// wasn't found - construct error message
StringBuilder locationsText = new StringBuilder();
foreach (string location in viewResult.SearchedLocations)
{
locationsText.AppendLine();
locationsText.Append(location);
}
throw new InvalidOperationException(String.Format("View {0} not found. Locations Searched: {1}", viewName, locationsText));
}
}
Then, within your controller action methods you can use something similar to this:
string partial = RenderPartialToString("TestPartial", "This is my test partial");
string viewString = this. RenderViewToString("", null, "");
That will do very nice thanks
. I simiplified to this as well:
protected string RenderViewToString(ViewResult viewResult)
{
using (var sw = new StringWriter())
{
var viewContext = new ViewContext(ControllerContext, viewResult.View, viewResult.ViewData, viewResult.TempData, sw);
viewResult.View.Render(viewContext, sw); ;
return sw.GetStringBuilder().ToString();
}
}