2017-03-22 21 views
0

我试图实现在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-featuresDISPLAYMODE不改变到移动视图当控制器操作包含视图路径

虽然上面向着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(); 
     } 
    } 
} 

而且我有两个意见 “〜/查看/测试” 文件夹:

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.Mobile.cshtml请求时,它从一个移动模拟器请求时,它Test.cshtml)获取正确的观点。但是,当要求/测试/测试2时,我总是得到桌面视图。

我已经搜索了一个解决方案来解决我的问题,但是似乎每个人都会一遍又一遍地重现相同的情况(即“/ test/test”场景),而且似乎没有人试图执行“/ test/test2“场景。是否可以重写该功能?我不害怕用重写默认剃须刀/ MVC功能弄脏我的手,但我真的不知道从哪里开始。

任何帮助表示赞赏。

回答

1

我不知道有关重写此功能,但可以使用自定义RazorViewEngine类并覆盖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()) 
+0

我希望有一些没有触及控制器代码库的东西。另外,它不像DisplayMode解决方案那么通用 - 如果我想要投入“平板电脑”模式,然后是“LegacyPhone”模式等,该怎么办?这些类型的行为的return语句很快就会变得非常繁琐。 – Yiangos

+0

对于更通用的解决方案,您可以通过继承RazorViewEngine类创建自己的自定义视图引擎,并使用base.FindView方法设置您想要特定视图的路径。这样,你所有的设备检查将在一个地方。 –

+0

这听起来不正确。我的问题是当返回的View对象已经在构造函数参数中声明了一个viewpath时。我的理解是FindView方法在这种情况下不会被调用 - 引擎已经知道在哪里搜索视图。不过,我会试着看看它是否被调用,如果是的话,我会在那里塞进一些设备检测逻辑。我会让你知道结果,尽管我现在有点悲观。 – Yiangos

相关问题