根据是否设置“beta”cookie显示不同的视图

时间:2014-04-05 21:12:08

标签: asp.net asp.net-mvc razor asp.net-mvc-5

我有一个有效的MVC网站。为了增加其视觉吸引力,我想重新创建所有视图以使用Bootstrap。这不需要对模型或控制器进行任何更改。

在过渡期间,我希望根据是否设置特定的“Beta模式”cookie,将用户定向到不同的视图。例如,他们将被引导到以下之一:

Index.cshtml
Index.beta.cshtml

如何在不更改每个控制器中的代码的情况下完成此操作?

2 个答案:

答案 0 :(得分: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());

答案 1 :(得分: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会对Jack的IsBeta方法产生类似的影响。

您还需要在global.asax中注入IBetaCookieChecker,或许像ViewEngines.Engines.Add(new ToolsViewEngine(container.Resolve<IBetaCookieChecker>()));