Adventures on the edge

Learning new development technologies
    "When living on the bleeding edge - you sometimes have to bleed" -BillKrat

ASP.NET MVC - RenderViewToString in MVC 6

The plumbing has changed with ASP.NET MVC 6 requiring us to think differently, particularly with inversion of control (aka dependency injection) now being a first class citizen.

In my latest adventure, my goal was focused on building a reusable class that allows me to convert a View into a string. This can be used for generating emails, newsletters, or insertion into other views.

To achieve this objective, I dug into the ASP.NET MVC source code to see how it works under the hood (reference blog “how to setup for using / debugging open source code”). To make this work I had to find the parameters required by the view engine’s FindView method and the view’s RenderAsync method.

I then created a new MVC website to prove out the code and updated the HomeController so that the About view injected the Contact views content:

Output

The about.cshtml view was updated to display the raw data provided by the HomeController (line 10 in image below).

AboutView

With the view done, I complied with the following steps within the HomeController class:

  1. Paste the ViewHelper class code into the HomeController (source available at end of this blog)
  2. Update the HomeController constructor so that dependency injection will resolve the ViewHelper via constructor injection (and as a result, its dependencies)
  3. Update the About() method to set ViewData[“Contact”] with the rendered content of the Contact view (on line 65-66 below).

ControllerSource

Perhaps the most important and final step is to ensure the dependency injection container knows about the ViewHelper - this is done on line 49 below in the Startup.ConfigureServices() method.

Ioc

 

public class ViewHelper
{
private IRazorViewEngine _viewEngine;
private ITempDataDictionary _tempDataDict;

public ViewHelper(
IRazorViewEngine viewEngine,
ITempDataDictionary dataDict,
IHtmlHelper helper)
{
_viewEngine = viewEngine;
_tempDataDict = dataDict;
}

public string RenderToString(
string viewName,
ActionContext actionContext,
ViewDataDictionary viewData)
{
using (var stringWriter = new StringWriter())
{
var viewEngineResult =
_viewEngine.FindView(actionContext, viewName);

var viewContext = new ViewContext(
actionContext,
viewEngineResult.View,
viewData,
_tempDataDict,
stringWriter,
new HtmlHelperOptions());

viewEngineResult.View.RenderAsync(viewContext);

var result = stringWriter.GetStringBuilder().ToString();
return result;
}
}
}
Comments are closed