我有一個正在工作的MVC站點。爲了增加視覺吸引力,我想重新創建所有使用Bootstrap的視圖。這不需要對模型或控制器進行任何更改。根據是否設置「測試版」cookie顯示不同視圖
在過渡期間,我希望根據是否設置特定的「測試模式」cookie來將用戶定向到不同的視圖。例如,他們會被引導到一個:
Index.cshtml
Index.beta.cshtml
如何才能做到這一點,而無需更改每一個控制器的代碼?
我有一個正在工作的MVC站點。爲了增加視覺吸引力,我想重新創建所有使用Bootstrap的視圖。這不需要對模型或控制器進行任何更改。根據是否設置「測試版」cookie顯示不同視圖
在過渡期間,我希望根據是否設置特定的「測試模式」cookie來將用戶定向到不同的視圖。例如,他們會被引導到一個:
Index.cshtml
Index.beta.cshtml
如何才能做到這一點,而無需更改每一個控制器的代碼?
類似的答案,傑克..
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>()));
在我關聯的帖子之後,我做了一個天真的實現。注意:這是
未經測試的
測試。對於我的測試,我硬編碼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());
你看着重寫視圖引擎? 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