Thursday 27 November 2014

Rendering ASP.NET MVC Views to HTML String

A common need I have in my ASP.NET MVC based projects is to render a complete "View" or "PartialView" to string instead of the HTTP response and then present it or embed it in another rendered view.

You can implement the following code in shared controller or preferably in base Controller so that you can access this function in all controllers across your project. You can access the ControllerContext within controller and pass it to the function. It will return the rendered view in HTML string, the usage is self-explanatory.

public static string RenderViewToString(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();
 }
}

ControllerContext can be access using following method.

ControllerContext.RouteData.GetRequiredString("action");

If you want to put the function in a helper class you have to pass the ControllerContext from controller to the function.

public static string RenderViewToString(ControllerContext context, string viewName, object model) 
{
 if (string.IsNullOrEmpty(viewName)) 
     viewName = context.RouteData.GetRequiredString("action");
 
 var viewData = new ViewDataDictionary(model);
 using(var sw = new StringWriter()) 
 {
  var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
  var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
  viewResult.View.Render(viewContext, sw);
  return sw.GetStringBuilder().ToString();
 }
}

Call the function in your Action Method

//Somewhere in HomeController
public ActionResult Index() 
{
 //Second parameter(model) can be null
 var context = ControllerContext.RouteData.GetRequiredString("action");
 var content = RenderViewToString(context, "profile", new ProfileModel());
 //var content = RenderViewToString("profile", new ProfileModel());

 
        //Do something with the content, e.g.get profile specific template and send it to e-mail


 //This does nothing to do with rendered string
 return View();
}


/Adnan

About the Author

Adnan Zameer, Lead Developer at Optimizley UK, is a certified Microsoft professional, specializing in web app architecture. His expertise includes Optimizley CMS and Azure, showcasing proficiency in crafting robust and efficient solutions.

0 comments :

Post a Comment