2013-09-29 34 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这也说明这一点。