I use the following types injected from the IServiceProvider
:
ICompositeViewEngine viewEngine;
ITempDataProvider tempDataProvider;
IHttpContextAccessor httpContextAccessor;
I render the content using the following method:
private async Task<string> RenderView(string path, ViewDataDictionary viewDataDictionary, ActionContext actionContext)
{
using (var sw = new System.IO.StringWriter())
{
var viewResult = viewEngine.FindView(actionContext, path);
var viewContext = new ViewContext(actionContext, viewResult.View, viewDataDictionary, new TempDataDictionary(httpContextAccessor, tempDataProvider), sw);
await viewResult.View.RenderAsync(viewContext);
sw.Flush();
if (viewContext.ViewData != viewDataDictionary)
{
var keys = viewContext.ViewData.Keys.ToArray();
foreach (var key in keys)
{
viewDataDictionary[key] = viewContext.ViewData[key];
}
}
return sw.ToString();
}
}
I call it like this:
var path = "~/Views/Home/Index.cshtml";
var viewDataDictionary = new ViewDataDictionary(new Microsoft.AspNet.Mvc.ModelBinding.EmptyModelMetadataProvider(), new Microsoft.AspNet.Mvc.ModelBinding.ModelStateDictionary());
var actionContext = new ActionContext(httpContextAccessor.HttpContext, new Microsoft.AspNet.Routing.RouteData(), new ActionDescriptor());
viewDataDictionary.Model = null;
var text = await RenderView(path, viewDataDictionary, actionContext);
Of course, my viewDataDictionary
and actionContext
variables are set by another method for encapsulation. A modification to the new ViewDataDictionary
line can result in a typed Model being bound to your View if you choose.
This code uses heavy usings, I think I've listed them below. Otherwise, VS2015 is pretty good about finding them.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
This was written under beta-3; it still builds, but some things may change. I'll try to come back here to update if it does.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…