App.WebApp.Views是我在一个解决方案中的项目,我将 View 放入App.Views中并用RazorGenerator预编译。如果我像这样使用App.Web,效果很好



它可以在App.Web中成功呈现此 View

public ActionResult Index() {
  return View("~/Views/Index.cshtml");
}

但是当我尝试RenderViewToString时,它返回null
class FakeController : ControllerBase
{
    protected override void ExecuteCore() { }
    public static string RenderViewToString(string controllerName, string viewName, object viewData)
    {
        using (var writer = new StringWriter())
        {
            var routeData = new RouteData();
            routeData.Values.Add("controller", controllerName);
            var fakeControllerContext = new ControllerContext(new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://google.com", null), new HttpResponse(null))), routeData, new FakeController());
            var razorViewEngine = new RazorViewEngine();
            var razorViewResult = razorViewEngine.FindView(fakeControllerContext, viewName, "", false);
            var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View, new ViewDataDictionary(viewData), new TempDataDictionary(), writer);
            razorViewResult.View.Render(viewContext, writer);
            return writer.ToString();
        }
    }
}

这是怎么回事,
FakeController.RenderViewToString("FakeName", "~/Views/Index.csthml", MessageModel);

asp.net - RazorViewEngine.FindView找不到预编译的 View-LMLPHP

This is discussed and probably solved in asp.net core,但我正在使用asp.net mvc 5。

您能帮我弄清楚为什么它不起作用吗?

最佳答案

您正在尝试使用Razor View Engine获取预编译的 View 。这是个错误。 Razor引擎基于cshtml文件生成 View 。但是,在使用预编译 View 的情况下,RazorGenerator已将cshtml文件编译为从System.Web.Mvc.WebViewPage派生的一组类。这些类覆盖方法Execute()(由RazorGenerator基于输入cshtml自动生成),该方法将html写入以输出TextWriter
不再需要原始 View 文件(cshtml),因此不会与应用程序一起部署。当您调用试图定位cshtml并基于其构建 View 的Razor时,它预期会返回null View 。

ASP.NET MVC支持多个 View 引擎(实现System.Web.Mvc.IViewEngine的类)。 RazorViewEngine是其中之一。 RazorGenerator.Mvc NuGet软件包添加了自己的 View 引擎(PrecompiledMvcEngine),该引擎基于预编译的 View 工作。注册的 View 引擎存储在ViewEngines.Engines集合中。当您安装RazorGenerator.Mvc NuGet软件包时,它将添加RazorGeneratorMvcStart类,该类注册PrecompiledMvcEngine的实例:

[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(App.Views.RazorGeneratorMvcStart), "Start")]

namespace App.Views {
    public static class RazorGeneratorMvcStart {
        public static void Start() {
            var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) {
                UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
            };

            ViewEngines.Engines.Insert(0, engine);

            // StartPage lookups are done by WebPages.
            VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
        }
    }
}

您应使用PrecompiledMvcEngine的此实例而不是RazorViewEngine来访问预编译的 View 。这是RenderViewToString方法的调整后的代码:
public static string RenderViewToString(string controllerName, string viewName, object viewData)
{
    using (var writer = new StringWriter())
    {
        var routeData = new RouteData();
        routeData.Values.Add("controller", controllerName);
        var fakeControllerContext = new ControllerContext(new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://google.com", null), new HttpResponse(null))), routeData, new FakeController());
        var viewEngine = ViewEngines.Engines.OfType<PrecompiledMvcEngine>().FirstOrDefault();
        if (viewEngine == null)
        {
            throw new InvalidOperationException("PrecompiledMvcEngine is not registered");
        }
        var viewResult = viewEngine.FindView(fakeControllerContext, viewName, "", false);
        var viewContext = new ViewContext(fakeControllerContext, viewResult.View, new ViewDataDictionary(viewData), new TempDataDictionary(), writer);
        viewResult.View.Render(viewContext, writer);
        return writer.ToString();
    }
}

一个重要的注意事项:应该将RazorGenerator.Mvc NuGet软件包与 View 一起安装到项目中(App.Views),而不是Web应用程序项目中,因为PrecompiledMvcEngine将当前程序集用作预编译 View 的源。 Aslo确保未将RazorGeneratorMvcStart添加到App.Web项目中。当我添加了对RazorGenerator.Mvc.dll程序集的引用时,它就发生了。

Sample Project on GitHub

关于asp.net - RazorViewEngine.FindView找不到预编译的 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49399800/

10-08 20:44