[英]Load Razor Views From Database in ASP.NET MVC 5
We are trying to develop a corporate CMS application in ASP.NET MVC 5. The user needs to create a new page, change an existing page content or delete a page alltogether from an admin application. 我们正在尝试在ASP.NET MVC 5中开发企业CMS应用程序。用户需要创建新页面,更改现有页面内容或从管理应用程序中完全删除页面。 Another requirement states that some of the pages can include custom widgets which were written in Razor syntax. 另一个要求是,某些页面可以包含使用Razor语法编写的自定义小部件。
These 2 requirements lead me to load razor views from the database. 这两个要求使我从数据库加载剃刀视图。 I googled and find a couple of examples. 我用Google搜索并找到了几个例子。
The first one is to extend the VirtualPathProvider and register it with the expression below in the Application_Start method. 第一个是扩展VirtualPathProvider并在Application_Start方法中使用下面的表达式注册它。
protected void Application_Start()
{
...
HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider());
}
When I try to run this, it throws the error below 当我尝试运行它时,它会抛出下面的错误
[InvalidOperationException: The view at '~/Views/Home/Index.aspx' must derive from ViewPage, ViewPage, ViewUserControl, or ViewUserControl.] System.Web.Mvc.WebFormView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +180 System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +291 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52 System.Web.Mvc.Async.c__DisplayClass2b.b__1c() +173 System.Web.Mvc.Async.c__DisplayClass21.b__1e(IAsyncResult asyncResult) +100 System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller) +12 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9644097 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Another example is 另一个例子是
protected void Application_Start()
{
...
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MyViewEngine());
}
private class MyViewEngine : RazorViewEngine
{
public MyViewEngine()
{
this.VirtualPathProvider = new MyVirtualPathProvider();
}
}
This one works when the specified file (eg /View/Home/Index.cshtml) is in the file system even it has nothing in it. 当指定的文件(例如/View/Home/Index.cshtml)在文件系统中时,即使它没有任何内容,也可以使用此文件。 When I delete the file from the file system, the error below is thrown 当我从文件系统中删除文件时,会抛出以下错误
[InvalidOperationException: The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Home/Index.cshtml ~/Views/Home/Index.vbhtml ~/Views/Shared/Index.cshtml ~/Views/Shared/Index.vbhtml] System.Web.Mvc.ViewResult.FindView(ControllerContext context) +382 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +116 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52 System.Web.Mvc.Async.c__DisplayClass2b.b__1c() +173 System.Web.Mvc.Async.c__DisplayClass21.b__1e(IAsyncResult asyncResult) +100 System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller) +12 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9644097 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
The RazorViewEngine tries to find the file in the file system even if you override the VirtualPathProvider to load view data from the database. 即使您重写VirtualPathProvider以从数据库加载视图数据,RazorViewEngine也会尝试在文件系统中查找该文件。
I guess the examples work in the previous versions of ASP.NET MVC (I think 2 or 3). 我想这些例子在以前版本的ASP.NET MVC中工作(我认为2或3)。 The best solution that I got is to write a custom view engine from scratch, but there are too much work to be done to make it work like the razor view engine. 我得到的最好的解决方案是从头开始编写自定义视图引擎,但是要做的工作太多,以使其像剃刀视图引擎一样工作。 Is there any other trick to make these examples work, or any other alternatives? 有没有其他技巧可以使这些示例有效,或者其他任何替代方案?
Have a look on these links. 看看这些链接。 Hope this might help. 希望这可能有所帮助。
http://rebuildall.umbraworks.net/2009/11/17/ASP_NET_MVC_and_virtual_views http://rebuildall.umbraworks.net/2009/11/17/ASP_NET_MVC_and_virtual_views
Using custom VirtualPathProvider to load embedded resource Partial Views 使用自定义VirtualPathProvider加载嵌入式资源部分视图
Storing ASP.Net MVC Views in the Database 在数据库中存储ASP.Net MVC视图
ASP.NET MVC load Razor view from database ASP.NET MVC从数据库加载Razor视图
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.