在之前的ASP.NET版本中,虽然不是很简单,但是可以将Razor视图呈现为字符串。我看到的方法是使用假控制器,或者使用一些外部引擎,如RazorEngine。
现在,在ASP.NET 5中有很多改变,我想知道是否比以前更简单了。所以在新版本的框架中,是否有一种直接的方法来将Razor视图呈现为字符串,还是我们仍然需要使用以前版本中的方法?
在之前的ASP.NET版本中,虽然不是很简单,但是可以将Razor视图呈现为字符串。我看到的方法是使用假控制器,或者使用一些外部引擎,如RazorEngine。
现在,在ASP.NET 5中有很多改变,我想知道是否比以前更简单了。所以在新版本的框架中,是否有一种直接的方法来将Razor视图呈现为字符串,还是我们仍然需要使用以前版本中的方法?
我使用从IServiceProvider
注入的以下类型:
ICompositeViewEngine viewEngine;
ITempDataProvider tempDataProvider;
IHttpContextAccessor httpContextAccessor;
我使用以下方法呈现内容:
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();
}
}
我把它叫做这个:
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);
当然,我的viewDataDictionary
和actionContext
变量是由另一个方法设置的,以实现封装。如果您选择修改new ViewDataDictionary
行,可能会导致类型化模型绑定到您的视图。此代码使用了大量的using
语句,我认为我已经在下面列出了它们。否则,VS2015可以很好地找到它们。using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
这篇文章是在beta-3下撰写的;它仍然可以构建,但有些东西可能会发生变化。如果有变化,我会尽力回来更新这里。
我曾在一年前使用过一种解决方案。我不确定是否有新的/更好的方法来解决问题,但它可以解决问题。
public string RenderViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}