2011-11-16 51 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')。後者更棘手,因爲您需要根據目標類型邏輯分隔視圖定位邏輯。 –