当控制器操作包含视图路径时,DisplayMode 不会更改为移动视图

DisplayMode doesn't change to mobile view when controller action contains view path

我正在尝试在 ASP.NET MVC 应用程序中实现特定于设备的视图,例如这里: https://www.simple-talk.com/dotnet/asp-net/multiple-views-and-displaymode-providers-in-asp-net-mvc-4/ 或在这里: https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/aspnet-mvc-4-mobile-features

虽然上面的文章是针对 ASP.NET MVC4 的,但它们的内容与框架的更高版本相关(我的应用程序使用的是 ASP.NET MVC 5.2)。

我偶然发现了一个问题。我有以下控制器:

public class TestController: Controller
{
    public ActionResult Test()
    {
        return View(new TestModel());
    }
    public ActionResult Test2()
    {
        return View("~/Views/Test/Test.cshtml", new TestModel());
    }
}

测试模型非常基础:

public class TestModel
{
    public string TheDate
    {
        get
        {
            return DateTime.Now.ToString();
        }
    }
}

我在“~/Views/Test”文件夹中有两个视图:

Test.cshtml

@model MyNamespace.Models.TestModel
<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<h1>This is the desktop view</h1>
<p>model data: @Model.TheDate</p>
</body>
</html>

Test.Mobile.cshtml

@model MyNamespace.Models.TestModel
<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<h1>This is the mobile view</h1>
<p>model data: @Model.TheDate</p>
</body>
</html>

我已经实施了上面链接中描述的解决方案。

当请求 /test/test 时,我得到了正确的视图(通过我的桌面浏览器请求它时 Test.cshtml 和从移动模拟器请求它时 Test.Mobile.cshtml )。但是,当请求 /test/test2 时,我总是得到桌面视图。

我已经为我的问题寻找了解决方案,但似乎每个人都一遍又一遍地重现相同的场景(即“/test/test”场景),而且似乎没有人尝试过“ /test/test2”场景。甚至可以覆盖该功能吗?我不怕弄脏我的手来覆盖默认 razor/MVC 功能,但我真的不知道从哪里开始。

感谢任何帮助。

我不确定是否覆盖此功能,但您可以使用自定义 RazorViewEngine class 并覆盖 FindView 方法,并在其中检测移动设备使用 Request.Browser.IsMobileDevice 作为解决方法,如下所示:

public class CustomViewEngine : RazorViewEngine
{
      public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
      {
           var viewPath = controllerContext.HttpContext.Request.Browser.IsMobileDevice ? "MobilePath" : "defaultPath";

           return base.FindView(controllerContext, viewPath, "MasterName", useCache);
      }
}

不要忘记在 Application_Start 中注册您的自定义视图引擎,如下所示:

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