2013-09-29 63 views
0

我想根據我塞在傳遞切換視圖......我可以確認的蛞蝓和邏輯是正確的,但我的觀點是沒有發現:MVC4(FixedRazorViewEngine)沒有找到我的看法

全球.asax.cs:

ViewEngines.Engines.Clear(); 
ViewEngines.Engines.Add(new DeviceCapableViewEngine()); 

      DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("mobile") 
      { 
       ContextCondition = Context => Context.Request.Browser["IsMobile"] == "True" 
               && Context.Request.Browser["IsTablet"] == "False" 
      }); 

      DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("") 
      { 
       ContextCondition = Context => Context.Request.Browser["IsMobile"] == "False" 
               || Context.Request.Browser["IsTablet"] == "True" 
      }); 

DeviceCapableViewEngine:

public class DeviceCapableViewEngine : FixedRazorViewEngine 
    { 
     public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 
     { 
      ViewEngineResult result = null; 
     switch (ThemeContext.GetTheme()) 
     { 
      case "Blue": 
       result = base.FindView(controllerContext, string.Format("{0}.{1}", viewName, "blue"), masterName, useCache); 
       break; 
      case "Red": 
       result = base.FindView(controllerContext, string.Format("{0}.{1}", viewName, "red"), masterName, useCache); 
       break; 
     } 

     if (result == null || result.View == null) 
      result = base.FindView(controllerContext, viewName, masterName, useCache); 

     return result; 
    } 

我有一個相當標準的設置,我可以證實, 「藍」 或 「紅色」 斷點被擊中。如果他們是我不希望MVC注入「.mobile」...而是我希望它是「viewName.red」...但它似乎與我的DDR,它總是會嘗試找到.mobile與基地呼叫,這是真的嗎?

無論如何它都會返回「viewName.mobile」。有什麼我做錯了嗎?

+0

也許不相關,但:您是否檢查過有像「viewName.red.csthml」這樣的結果對應的文件?檢查結果的「SearchedLocations」以查看它是否看起來不在您期望的位置... –

回答

0

我有同樣的問題(original post)。當你調用base.FindView時,你傳遞了controllerContext作爲參數之一。在那裏,viewEngine實際上查看上下文,如果Mobile標誌設置爲true,它將嘗試在[viewname]之前查找[viewname] .mobile。

我想出的解決方案(坦率地說是更優雅的IMO)是根據設備將視圖放入單獨的文件夾中,然後在自定義視圖引擎中更改查看視圖的位置。這將根據設備提供視圖的邏輯分離以及簡化視圖引擎。

所以你的觀點引擎會是這個樣子:

string myViewName = viewName; 

switch (ThemeContext.GetTheme()) 
{ 
    case "Blue": 
     myViewName += ".blue"; 
     break; 
    case "Red": 
     myViewName += ".red";     
     break; 
} 

if (mobileViewShouldNotBeDisplayed) 
{ 

    ViewLocationFormats = new[] 
    { 
     "~/Views/{1}/{0}.cshtml" 
    }; 
} 
if (mobileViewShouldBeDisplayed) 
{ 

    ViewLocationFormats = new[] 
    { 
     "~/Views/{1}/Mobile/{0}.cshtml" 
    }; 
} 

我已經全部細節寫入一個blog post這也說明這一點。