Asp.net mvc 3 ASP.NET MVC 3.0 Razor,从任何开箱即用的地方加载视图?

Asp.net mvc 3 ASP.NET MVC 3.0 Razor,从任何开箱即用的地方加载视图?,asp.net-mvc-3,razor,Asp.net Mvc 3,Razor,是否可以从任何位置加载视图,而不必 在MVC 3.0中实现自定义VirtualPathProvider 如果这是真的,怎么做 基本上,实现将加载 从任何地方查看,但我的实现仅在MVC 2.0中工作,而不在MVC 3.0中工作,因此某种原因方法GetFilenewer在MVC 3.0中调用了不存在的视图,在这种情况下,我在“/”应用程序中得到了“服务器错误。” 我在这里为我的自定义VirtualPathProvider遵循了相同的代码: 更新1 好的,在我将自定义VirtualPathProvid

是否可以从任何位置加载视图,而不必 在MVC 3.0中实现自定义
VirtualPathProvider

如果这是真的,怎么做

基本上,实现将加载 从任何地方查看,但我的实现仅在MVC 2.0中工作,而不在MVC 3.0中工作,因此某种原因方法
GetFile
newer在MVC 3.0中调用了不存在的视图,在这种情况下,我在“/”应用程序中得到了“
服务器错误。

我在这里为我的自定义
VirtualPathProvider
遵循了相同的代码:

更新1

好的,在我将自定义
VirtualPathProvider
提供程序的注册放在应用程序的第一行\u Start()之后,我确实解决了自定义
VirtualPathProvider
提供程序的问题

Global.asax.cs
AreaRegistration.RegisteralAreas()之后注册自定义VirtualPathProvider时或<代码>注册表项(RouteTable.Routes)方法方法
覆盖虚拟文件GetFile(字符串virtualPath)
不适用于“虚拟视图”

更新2

这是否意味着类
RazorView
razorviewengineerender
就是答案

更新3

如果我有文件系统中不存在的razor视图的字符串表示(例如,我将razor视图存储在数据库中),我如何使用这种方法渲染它

例如,“我的视图”的字符串表示形式如下所示:

"@{
    ViewBag.Title = ""About Us"";
}

<h2>About</h2>
<p>
     Put content here.
</p>"
”@{
ViewBag.Title=“”关于我们“;
}
关于

把内容放在这里。

更新4

现在我明白了,为了能够使用
@Html。
应该实现自定义模板库。
HtmlTemplateBase
的实现示例可以在这里找到,但它在RazorEngine v2中不起作用,我正在成功编译模板,然后在程序集加载后,将不会执行方法
public override void Execute()
,我收到一个错误:该方法或操作未实现(stacktrace:)


为了实现“公共覆盖T模型”,我在“公共抽象类TemplateBase:TemplateBase,ITemplate”中将“公共TModel模型”的声明更改为“公共虚拟TModel模型”。可能还有一些其他的改变应该做吗?或者
HtmlTemplateBase
中的某些内容应该以另一种方式执行?

否,默认情况下不支持从数据库加载视图。您需要编写自己的
VirtualPathProvider


请注意,Ben的博客文章实际上并没有直接解决您试图解决的问题。下面的博文看起来更接近您想要的内容:。请注意,在数据库中存储razor或aspx视图并不重要。Asp.Net中的虚拟路径提供程序只是将一条路径映射到一个字节流,该字节流是由该路径表示的文件内容。

不要被Ben在其文章中(@BuildStarted)的示例代码所迷惑。他详细介绍了如何使用Razor ViewEngine的早期版本在不使用控制器操作的情况下渲染模板。其目的是能够以通用方式呈现模板,而不是作为特定的页面视图。(这就是我们的RazorEngine模板框架@的演变过程)

VirtualPathProvider
仍然是ASP.NET的核心部分。MVC 3的
DependencyResolver
取代了
VirtualPathProvider
,这似乎是一个普遍的困惑,但事实并非如此,您仍然需要一个提供者能够访问虚拟路径上的内容(顺便说一句,ASP.NET中的所有路径都是虚拟的)

回到我原来的答案,您应该能够通过对
RazorViewEngine
子类化并使用它创建视图来实现您想要的


看一看这个主题:

我在为嵌入式资源视图实现VirtualPathProvider时遇到了类似的问题。解决方案是实现GetFolder和GetFile。当您请求视图时,视图引擎不仅仅调用GetFile。在第一个请求中,它会查看views文件夹以查找所有可用的视图。如果该调用未将您的数据库视图包含在列表中,则在您尝试加载它们时将找不到它们。

每个人都是正确的。我的帖子不是如何加载Razor作为替代品,而是作为一种不用MVC调用Razor的方式。现在…你想要的很可能与我的帖子有关,我在这里展示了如何创建自己的ViewEngine来承载一个razor页面。它使用相同的引擎@Matthew Abbott和我用于RazorEngine的引擎-你可以从中获得。不幸的是,它不完整,但它应该给你一个如何做的想法。(我也会把它贴在这里)

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.Mvc;
使用System.Web.Hosting;
使用System.IO;
使用System.Text.RegularExpressions;
使用System.Xml.Linq;
命名空间RazorViewEngine{
/// 
///RazorView的ViewEngine。提供加载视图的基本文件处理。
/// 
公共类RazorViewEngine:IViewEngine{
字符串[]搜索位置{get;set;}
元组缓存{get;set;}
VirtualPathProvider VirtualPathProvider{get;set;}
公共RazorViewEngine(){
//{1} ==控制器名称
//{0}==视图名称
SearchLocations=新字符串[]{
“~/Views/{1}/{0}.cshtml”,
“~/Views/Shared/{0}.cshtml”,
};
VirtualPathProvider=HostingEnvironment.VirtualPathProvider;
}
#区域IViewEngine成员
公共视图引擎结果FindPartialView(ControllerContext ControllerContext、字符串partialViewName、布尔useCache){
返回CreateView(控制器
"@{
    ViewBag.Title = ""About Us"";
}

<h2>About</h2>
<p>
     Put content here.
</p>"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Hosting;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml.Linq;

namespace RazorViewEngine {
    /// <summary>
    /// ViewEngine for the RazorView. Provides basic file handling to load views. 
    /// </summary>
    public class RazorViewEngine : IViewEngine {

        string[] SearchLocations { get; set; }
        Tuple<string, string, RazorView> Cache { get; set; }
        VirtualPathProvider VirtualPathProvider { get; set; }

        public RazorViewEngine() {
            //{1} == Controller name
            //{0} == View name
            SearchLocations = new string[] {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/Shared/{0}.cshtml",
            };

            VirtualPathProvider = HostingEnvironment.VirtualPathProvider;
        }

        #region IViewEngine Members

        public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) {
            return CreateView(controllerContext, partialViewName, null, null, useCache);
        }

        public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
            return CreateView(controllerContext, viewName, masterName, GetLayoutPath(controllerContext), useCache);
        }

        /// <summary>
        /// Meat of the FindView methods.
        /// </summary>
        /// <param name="controllerContext">The current controller context for this request.</param>
        /// <param name="viewName">The requested view name. </param>
        /// <param name="masterName">The master page view name (currently unused)</param>
        /// <param name="layoutPath">The layout path location (Replaces the masterpage in other view engines)</param>
        /// <param name="useCache">Cache the viewpage?</param>
        /// <remarks>The layout path is currently hardcoded to "Layout" and will look in the SearchLocations for that path</remarks>
        /// <returns>Returns a ViewEngineResult with the requested view</returns>
        public ViewEngineResult CreateView(ControllerContext controllerContext, string viewName, string masterName, string layoutPath, bool useCache) {
            //grab the current controller from the route data
            string controllerName = controllerContext.RouteData.GetRequiredString("controller");

            //for proper error handling we need to return a list of locations we attempted to search for the view
            string[] SearchedLocations;

            //get the actual path of the view - returns null if none is found
            string viewPath = GetViewPath(viewName, controllerName, out SearchedLocations);

            if (viewPath != null) {
                RazorView view = new RazorView(this, controllerContext, viewPath, layoutPath);
                return new ViewEngineResult(view, this);
            }

            //we couldn't find the view - return an array of all locations we've looked in
            return new ViewEngineResult(SearchedLocations);
        }

        /// <summary>
        /// Look for the view in the current file system
        /// </summary>
        /// <param name="viewName">The name of the View you're looking for</param>
        /// <param name="controllerName">Current controller name</param>
        /// <param name="SearchedLocations">out a list of locations searched</param>
        /// <returns>A string value of the relative path</returns>
        public string GetViewPath(string viewName, string controllerName, out string[] SearchedLocations) {
            return FindPath(viewName, controllerName, out SearchedLocations);
        }

        /// <summary>
        /// Look for the view in the current file system
        /// </summary>
        /// <param name="viewName">The name of the View you're looking for</param>
        /// <param name="controllerName">Current controller name</param>
        /// <param name="SearchedLocations">out a list of locations searched</param>
        /// <returns>A string value of the relative path</returns>
        public string FindPath(string viewName, string controllerName, out string[] SearchedLocations) {
            SearchedLocations = new string[SearchLocations.Length];

            for (int i = 0; i < SearchLocations.Length; i++) {
                string virtualPath = string.Format(SearchLocations[i], viewName, controllerName);

                SearchedLocations[i] = virtualPath;

                //check the active VirtualPathProvider if the file exists
                if (VirtualPathProvider.FileExists(virtualPath)) {
                    //add it to cache - not currently implemented
                    return VirtualPathProvider.GetFile(virtualPath).VirtualPath;
                }
            }

            return null;
        }

        /// <summary>
        /// Get the layout virtual path
        /// </summary>
        /// <param name="controllerContext">The current Controller context for this request</param>
        /// <returns>A string virtual path</returns>
        public string GetLayoutPath(ControllerContext controllerContext) {
            //This should probably be added to a list of locations - I'm not sure exactly
            //what I need to do with this yet.
            string[] locations;

            return FindPath("Layout", controllerContext.RouteData.GetRequiredString("controller"), out locations);
        }

        /// <summary>
        /// Current irrelevant
        /// </summary>
        /// <param name="controllerContext">The active controller context</param>
        /// <param name="view">View to release</param>
        public void ReleaseView(ControllerContext controllerContext, IView view) {
            IDisposable disposable = view as IDisposable;
            if (disposable != null) {
                disposable.Dispose();
            }
        }

        #endregion
    }

    /// <summary>
    /// Implements IView and renders a Razor
    /// </summary>
    public class RazorView : IView {

        ControllerContext ControllerContext;
        string ViewPath;
        string LayoutPath;
        RazorViewEngine Engine;

        public RazorView(RazorViewEngine engine, ControllerContext controllerContext, string viewPath, string layoutPath) {
            //load the file
            this.ControllerContext = controllerContext;
            this.ViewPath = viewPath;
            this.LayoutPath = layoutPath;
            this.Engine = engine;
        }

        #region IView Members

        /// <summary>
        /// Converts Razor to html and writes it to the passed in writer
        /// </summary>
        /// <param name="viewContext"></param>
        /// <param name="writer"></param>
        public void Render(ViewContext viewContext, System.IO.TextWriter writer) {
            //View contents
            string contents = new StreamReader(VirtualPathProvider.OpenFile(ViewPath)).ReadToEnd();
            string layoutContents = LayoutPath == null
                ? null
                : new StreamReader(VirtualPathProvider.OpenFile(LayoutPath)).ReadToEnd();

            contents = Parse(contents);

            string output;
            output = contents;

            writer.Write(output);
        }

        /// <summary>
        /// Converts Razor to html
        /// </summary>
        /// <param name="Razor">Razor text</param>
        /// <returns>Html formatted Razor text</returns>
        string Parse(string Razor) {

            //Where do I get the model From

            return RazorEngine.Razor.Parse(Razor);
        }

        #endregion
    }

}