Render Razor view to string in ASP.NET 5

前端 未结 2 862
死守一世寂寞
死守一世寂寞 2020-12-01 08:13

In previous versions of ASP.NET it was possible, although not very simple, to render Razor views as strings. The methods I\'ve seem are to use a fake controller, or also to

相关标签:
2条回答
  • 2020-12-01 08:50

    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.

    0 讨论(0)
  • 2020-12-01 08:51

    There is a solution that I've used an year ago. I'm not sure if there is a new/better way to do, but it solves the problem.

    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();
         }
    }
    
    0 讨论(0)
提交回复
热议问题