【问题标题】:MVC3 Custom view engineMVC3 自定义视图引擎
【发布时间】:2011-11-16 09:59:59
【问题描述】:

我有一个从 WebFormViewEngine 派生的自定义视图引擎。这里有很多东西,主要是缓存。我希望能够同时使用 WebFormViewEngine 和 RazorViewEngine,这可能吗?理想情况下我愿意这样做;

ViewEngines.Add(new MyViewEngine<WebFormsViewEngine>()); ViewEngines.Add(new MyViewEngine<RazorViewEngine>());

如果存在 .ascx/.aspx/.master 文件,则使用 WebForms,否则使用 Razor 是存在 .cshtml 文件。

编辑:我应该更好地措辞我的问题。由于我的自定义视图引擎从 WebFormViewEngine 派生,它显然使用 WebForms,我不能从两个类派生。我可以从 RazorViewEngine 派生,但随后我将失去 WebForms。我可以完全复制我的代码,从 RazorViewEngine 派生并编辑视图文件扩展名等,但正如我所说,我的视图引擎中有很多自定义代码,并且会复制数百行。

WebFormViewEngine 和 RazorViewEngine 派生自 BuildManagerViewEngine,后者又实现了 IViewEngine。问题是我必须实现方法 CreatePartialView() 和 CreateView() 但是我怎么知道使用泛型返回什么(WebForms/Razor?)?

【问题讨论】:

  • 我已经编辑了我的问题,我觉得我不够清楚。

标签: c# asp.net-mvc-3 razor webforms


【解决方案1】:

这是可能,但不推荐方式,因为它会给您的项目带来一些混乱。你可以阅读关于它的好文章:Using Multiple View Engines

【讨论】:

    【解决方案2】:

    应该没关系。

    默认情况下,MVC3 包括WebFormsViewEngineRazorViewEngine,它们都是自动注册的。我相信它们的顺序是WebFormsViewEngine,然后是RazorViewEngine,这意味着将首先检查网络表单视图。如果它找到一个视图,它将使用它。如果不能,它将使用下一个视图引擎,即 Razor 视图引擎。

    您是否尝试过删除自定义视图引擎并保留默认配置?

    【讨论】:

    • 是的,它确实有效。我需要自定义视图引擎,因为它有很多视图缓存。
    • 标准视图引擎中的现有缓存是否不适合您?我认为您可以采用两种方式之一。要么构建一个复合视图引擎,它依次检查WebFormsViewEngine,然后是RazorViewEngine,要么构建一个复合视图引擎来执行两个视图引擎的操作,但根据文件扩展名返回一个特定的IView选择的视图(覆盖CreateViewCreatePartialView 或您的VirtualPathProviderViewEngine)。后者更棘手,因为您需要根据目标类型对视图定位逻辑进行逻辑分离。
    【解决方案3】:

    最后我创建了一个抽象类:public abstract class MyViewEngine : BuildManagerViewEngine, IViewEngine { },然后实现/覆盖FindViewFindPartialView 方法(其中包含我的缓存代码)。我有一个抽象方法public abstract void SetSearchPaths();,在我的ctor 中调用。

    然后,我专门为 WebForms 创建了另一个派生自 MyViewEngine 的类:

    public class MyViewEngineWebForms : MyViewEngine
    {
        public override void SetSearchPaths()
        {
            base.MasterLocationFormats = new string[] { "~/Skins/{2}/Views/{1}/{0}.master", "~/Skins/{2}/Views/Shared/{0}.master" };
            base.ViewLocationFormats = new string[] { "~/Skins/{2}/Views/{1}/{0}.aspx", "~/Skins/{2}/Views/Shared/{0}.aspx", "~/Skins/Shared/Views/{0}.aspx" };
            base.PartialViewLocationFormats = new string[] { "~/Skins/{2}/Views/{1}/{0}.ascx", "~/Skins/{2}/Views/Shared/{0}.ascx", "~/Skins/Shared/PartialViews/{0}.ascx" };
            base.FileExtensions = new string[] { "aspx", "ascx", "master" };
        }
    
        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
        {
            return new WebFormView(controllerContext, partialPath, null, base.ViewPageActivator);
        }
    
        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {
            return new WebFormView(controllerContext, viewPath, masterPath, base.ViewPageActivator);
        }
    }
    

    并且对 Razor 执行了完全相同的操作,但将文件扩展名更改为 .cshtml/.vbhtml 并将 WebFormView 更改为 RazorView。将它们添加到 ViewEngine 集合中:

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new SeeTicketsWebFormsViewEngine());
    ViewEngines.Engines.Add(new SeeTicketsRazorViewEngine());
    

    现在它们又可以完美地工作了,与我所有的自定义缓存逻辑一起工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多