加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – RazorViewEngine.FindView无法找到预编译的视图

发布时间:2020-12-16 06:40:41 所属栏目:asp.Net 来源:网络整理
导读:App.Web和App.Views是我在一个解决方案中的项目,我将我的视图放在App.Views中并使用 RazorGenerator预编译.如果我使用App.Web之类的话,它运行良好, ~/Views/Index.cshtml is virtual path of my view in App.View 它可以在App.Web中成功呈现此视图 public Ac
App.Web和App.Views是我在一个解决方案中的项目,我将我的视图放在App.Views中并使用 RazorGenerator预编译.如果我使用App.Web之类的话,它运行良好,

~/Views/Index.cshtml is virtual path of my view in App.View

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

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);

enter image description here

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

你能不能帮我弄清楚,为什么它不起作用?

解决方法

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

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

[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);
        }
    }
}

您应该使用此PrecompiledMvc??Engine实例而不是RazorViewEngine来访问预编译视图.以下是RenderViewToString方法的调整代码:

public static string RenderViewToString(string controllerName,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,new FakeController());
        var viewEngine = ViewEngines.Engines.OfType<PrecompiledMvcEngine>().FirstOrDefault();
        if (viewEngine == null)
        {
            throw new InvalidOperationException("PrecompiledMvcEngine is not registered");
        }
        var viewResult = viewEngine.FindView(fakeControllerContext,false);
        var viewContext = new ViewContext(fakeControllerContext,viewResult.View,writer);
        viewResult.View.Render(viewContext,writer);
        return writer.ToString();
    }
}

一个重要的注意事项:您应该将RazorGenerator.Mvc NuGet包安装到带有视图的项目(App.Views)中,而不是安装到Web应用程序项目中,因为PrecompiledMvc??Engine将当前程序集作为预编译视图的源. Aslo确保没有将RazorGeneratorMvcStart添加到App.Web项目中.当我添加了对RazorGenerator.Mvc.dll程序集的引用时,它发生在我身上.

Sample Project on GitHub

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读