2014-04-05 36 views
1

我有一個正在工作的MVC站點。爲了增加視覺吸引力,我想重新創建所有使用Bootstrap的視圖。這不需要對模型或控制器進行任何更改。根據是否設置「測試版」cookie顯示不同視圖

在過渡期間,我希望根據是否設置特定的「測試模式」cookie來將用戶定向到不同的視圖。例如,他們會被引導到一個:

Index.cshtml 
Index.beta.cshtml 

如何才能做到這一點,而無需更改每一個控制器的代碼?

+1

你看着重寫視圖引擎? http://stackoverflow.com/questions/20071809/overriding-mvc-4-0-viewengine或http://stackoverflow.com/questions/13842638/mvc4-razor-custom-view-locator或http://博客。 thekfactor.info/posts/asp-net-mvc-custom-view-engines-using-the-razor-view-engine-as-the-base/ – Jack

回答

1

類似的答案,傑克..

public class BetaViewEngine : RazorViewEngine 
{ 
    private readonly IBetaCookieChecker _betaCookieChecker; 

    public ToolsViewEngine(IBetaCookieChecker betaCookieChecker) 
    { 
     _betaCookieChecker = betaCookieChecker; 
    } 

    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 
    { 
     if (_betaCookieChecker.UserHasBetaCookie()) 
     { 
      ViewLocationFormats = new[] 
       { 
        "~/Views/{1}/{0}.beta.cshtml", 
       }; 
      PartialViewLocationFormats = new[] 
       { 
        "~/Views/{1}/{0}.beta.cshtml", 
        "~/Views/Shared/{0}.beta.cshtml", 
       };     
     } 

     return base.FindView(controllerContext, viewName, masterName, useCache); 
    } 
} 

IBetaCookieChecker將有類似的IMPL傑克的IsBeta方法。

您還需要在Global.asax中注入IBetaCookieChecker也許像ViewEngines.Engines.Add(new ToolsViewEngine(container.Resolve<IBetaCookieChecker>()));

1

在我關聯的帖子之後,我做了一個天真的實現。注意:這是 未經測試的 測試。對於我的測試,我硬編碼IsBeta返回true,然後它找不到任何視圖(因爲我沒有名爲ViewName.beta.cshtml的視圖)。將Index.cshtml重命名爲Index.beta.cshtml後,它按預期解決了索引視圖。

public class BetaViewEngineTest : RazorViewEngine 
    { 
     public BetaViewEngineTest() : base() 
     { 
      AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}%1.cshtml", 
          "~/Areas/{2}/Views/{1}/{0}%1.vbhtml", 
          "~/Areas/{2}/Views/Shared/{0}%1.cshtml", 
          "~/Areas/{2}/Views/Shared/{0}%1.vbhtml" }; 
      AreaMasterLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}%1.cshtml", 
           "~/Areas/{2}/Views/{1}/{0}%1.vbhtml", 
           "~/Areas/{2}/Views/Shared/{0}%1.cshtml", 
           "~/Areas/{2}/Views/Shared/{0}%1.vbhtml" }; 
      AreaPartialViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}%1.cshtml", 
           "~/Areas/{2}/Views/{1}/{0}%1.vbhtml", 
           "~/Areas/{2}/Views/Shared/{0}%1.cshtml", 
           "~/Areas/{2}/Views/Shared/{0}%1.vbhtml" }; 
      ViewLocationFormats = new string[] { "~/Views/{1}/{0}%1.cshtml", 
         "~/Views/{1}/{0}%1.vbhtml", 
         "~/Views/Shared/{0}%1.cshtml", 
         "~/Views/Shared/{0}%1.vbhtml" }; 
      MasterLocationFormats = new string[] { "~/Views/{1}/{0}%1.cshtml", 
          "~/Views/{1}/{0}%1.vbhtml", 
          "~/Views/Shared/{0}%1.cshtml", 
          "~/Views/Shared/{0}%1.vbhtml" }; 
      PartialViewLocationFormats = new string[] { "~/Views/{1}/{0}%1.cshtml", 
          "~/Views/{1}/{0}%1.vbhtml", 
          "~/Views/Shared/{0}%1.cshtml", 
          "~/Views/Shared/{0}%1.vbhtml" }; 
      FileExtensions = new string[] { "cshtml", "vbhtml" }; 

     } 

     protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 
     { 
      return base.CreateView(controllerContext, IsBeta(controllerContext) ? viewPath.Replace("%1", ".beta") : viewPath.Replace("%1", ""), masterPath); 
     } 

     protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 
     { 
      return base.CreatePartialView(controllerContext, IsBeta(controllerContext) ? partialPath.Replace("%1", ".beta") : partialPath.Replace("%1", "")); 
     } 

     protected override bool FileExists(ControllerContext controllerContext, string virtualPath) 
     { 
      var isBeta = IsBeta(controllerContext); 
      if (isBeta) 
      { 
       return base.FileExists(controllerContext, virtualPath.Replace("%1", ".beta")); 
      } 
      else 
      { 
       return base.FileExists(controllerContext, virtualPath); 
      } 
     } 

     private bool IsBeta(ControllerContext ctx) 
     { 
      bool isBeta = false; 

      var httpCookie = ctx.HttpContext.Request.Cookies["Beta"]; 

      if (httpCookie != null) 
       Boolean.TryParse(httpCookie.Value, out isBeta); 

      return isBeta; 
     } 

    } 

差點忘了,Global.asax.cs中,添加這些行:

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