【问题标题】:Pre-compiled Razor view to string with ASP.NET Core使用 ASP.NET Core 将 Razor 视图预编译为字符串
【发布时间】:2016-12-04 23:21:41
【问题描述】:

如何在使用 ASP.NET Core 1.1 的新 Razor 预编译时将 Razor 视图呈现为字符串?

以下代码来自示例,由于viewResult.View 为空,将引发异常。

var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);

if (viewResult.View == null)
{
    throw new ArgumentNullException($"{viewName} does not match any available view");
}

https://blogs.msdn.microsoft.com/webdev/2016/10/25/announcing-asp-net-core-1-1-preview-1/


旧方式(示例):File -> Razor -> Compile -> string

【问题讨论】:

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


    【解决方案1】:

    它应该已经工作了。当你打电话时:

    viewResult.View.RenderAsync(viewContext);
    

    它将找到预编译的视图并使用该视图,而不是再次编译该视图。

    【讨论】:

    • 在到达这行代码之前抛出异常。
    • 我有同样的问题,这不是解决方案。作为@SeriousK。表示错误是在该行之前引发的。
    • 看看stackoverflow.com/a/50680245/1358684,如果有帮助就接受它作为答案。
    【解决方案2】:

    您必须实现 IViewRenderService 并在您的 Startup.cs 中注册。然后添加这样的函数:

    public class ViewRenderService : IViewRenderService
    {
        private readonly ITempDataProvider _tempDataProvider;
        private readonly IServiceProvider _serviceProvider;
        private readonly HttpContext _context;
        private readonly ICompositeViewEngine _viewEngine;
        private const string ControllerStr = "controller";
    
        public ViewRenderService(
            ITempDataProvider tempDataProvider,
            IServiceProvider serviceProvider,
            IHttpContextAccessor accessor,
            ICompositeViewEngine viewEngine)
        {
            _tempDataProvider = tempDataProvider;
            _serviceProvider = serviceProvider;
            _context = accessor.HttpContext;
            _viewEngine = viewEngine;
        }
    
        public async Task<string> RenderToStringAsync(string viewName, object model)
        {
            return await RenderToStringAsync(viewName, model, null);
        }
    
        public async Task<string> RenderToStringAsync(string viewName, object model, ViewDataDictionary viewDataDictionary)
        {
            var controller = string.Empty;
            viewName = viewName?.TrimStart(new char[] { '/' });
            Regex rex = new Regex(@"^(\w+)\/(.*)$");
            Match match = rex.Match(viewName);
            if (match.Success)
            {
                controller = match.Groups[1].Value;
                viewName = match.Groups[2].Value;
            }
    
            var routeData = new RouteData();
            routeData.Values.Add(ControllerStr, controller);
            var actionContext = new ActionContext(_context, routeData, new ActionDescriptor());
    
            var viewResult = _viewEngine.FindView(actionContext, viewName, false);
    
            if (viewResult.View == null)
            {
                Console.WriteLine($"Searched the following locations: {string.Join(", ", viewResult.SearchedLocations)} for folder \"{controller}\" and view \"{viewName}\"");
                throw new ArgumentNullException($"{viewName} does not match any available view");
            }
    
            var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
            {
                Model = model
            };
    
            if (viewDataDictionary != null)
            {
                foreach (var obj in viewDataDictionary)
                {
                    viewDictionary.Add(obj);
                }
            }
    
            using (var sw = new StringWriter())
            {
                var viewContext = new ViewContext(
                    actionContext,
                    viewResult.View,
                    viewDictionary,
                    new TempDataDictionary(_context, _tempDataProvider),
                    sw,
                    new HtmlHelperOptions()
                );
                viewContext.RouteData = _context.GetRouteData();
    
                await viewResult.View.RenderAsync(viewContext);
                return sw.ToString();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 2018-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 2018-09-09
      • 1970-01-01
      相关资源
      最近更新 更多