2011-11-16 84 views
2

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

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

如果一个的.ascx /的.aspx /的.master文件存在,那么使用的WebForms,否则使用剃刀是.cshtml文件存在。

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

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

+1

你试过了吗? – jgauffin

+0

我编辑了我的问题,我觉得我不够清楚。 – eth0

回答

1

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

然后我创建了一个从MyViewEngine导出的WebForms具体另一个类:

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

,准确地做了同样的剃刀,但更改文件扩展.cshtml/.vbhtml和更改WebFormViewRazorView。将它们添加到收藏ViewEngine

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

,现在他们又完全由侧与所有我的自定义缓存逻辑的工作,一边。

2

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

+0

我编辑了我的问题,我觉得我不够清楚。 – eth0

1

它应该没关系。

默认情况下,MVC3包括WebFormsViewEngineRazorViewEngine,这些都是自动注册的。我相信它们的订购顺序为WebFormsViewEngine,然后RazorViewEngine也意味着Web表单视图将首先被检查。如果它发现一个视图,它将使用它。如果它不能,它将使用下一个视图引擎,这是Razor视图引擎。

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

+0

是的,它确实有效。我需要自定义视图引擎,因为它有很多缓存视图。 – eth0

+1

标准视图引擎中的现有缓存是否不适合您?我认为你可以采取两种方式之一。或者构建一个复合视图引擎,它依次检查WebFormsViewEngine和RazorViewEngine,或者构建一个复合视图引擎来执行这两个视图引擎的操作,但根据文件扩展名返回一个特定的'IView'选择的视图(重写'CreateView','CreatePartialView'或你的'VirtualPathProviderViewEngine')。后者更棘手,因为您需要根据目标类型逻辑分隔视图定位逻辑。 –