在ASP.NET 5中将Razor视图渲染为字符串

时间:2015-05-20 23:39:31

标签: c# asp.net razor asp.net-core

在以前的ASP.NET版本中,将Razor视图呈现为字符串是可能的,尽管不是很简单。我看来的方法是使用假控制器,或者使用像RazorEngine这样的外部引擎。

现在,ASP.NET 5改变了很多东西,我想知道这是否比以前更简单。那么在框架的新版本中有一种直接的方式将Razor视图呈现为字符串,或者我们仍然需要使用以前版本中的方法吗?

2 个答案:

答案 0 :(得分:19)

我使用从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);

当然,我的viewDataDictionaryactionContext变量是由另一种封装方法设置的。如果您选择,对new ViewDataDictionary行的修改可能会导致键入的模型绑定到您的视图。

此代码使用大量使用,我想我已经在下面列出了它们。否则,VS2015非常适合找到它们。

using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;

这是在beta-3下写的;它仍在构建,但有些事情可能会改变。如果有的话,我会尝试回到这里进行更新。

答案 1 :(得分: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();
     }
}