我如何根据设备类型更改ASP.NET MVC视图?

Mat*_*tio 27 asp.net-mvc views mobile-devices

我正在通过一些ASP.NET MVC阅读工作,我有一个工作的Web应用程序,我将从WebForms迁移到MVC.我希望在此过程中获得的功能之一是,如果用户来自移动设备,则会返回简化视图.

我无法确定实现这种逻辑的最佳位置.我确信有一种比在每个返回视图的操作中为Browser.IsMobileDevice添加if/else更好的方法.我有什么样的选择呢?

Dal*_*gan 21

更新:此解决方案有一个微妙的错误.MVC框架将调用FindView/ FindPartialView两次:一次使用useCache=true,如果不返回结果,则调用一次useCache=false.由于所有类型的视图只有一个缓存,因此如果首先访问桌面浏览器,移动用户最终可能会看到桌面视图.

对于那些有兴趣使用自定义视图引擎来解决这个问题的人,Scott Hanselman在这里更新了他的解决方案:

http://www.hanselman.com/blog/ABetterASPNETMVCMobileDeviceCapabilitiesViewEngine.aspx

(对于答案劫持道歉,我只是不希望任何其他人必须经历这个!)

由roufamatic编辑(2010-11-17)


您要做的第一件事是将移动设备浏览器文件引入您的项目.使用此文件,您可以定位您想要支持的设备,而无需了解这些设备在其标头中发送的内容的具体信息.此文件已经为您完成了工作.然后,使用Request.Browser属性来定制要返回的视图.

接下来,提出一个关于如何在Views文件夹下组织视图的策略.我更喜欢将桌面版本保留在根目录下,然后使用Mobile文件夹.例如,Home视图文件夹看起来像这样:

    • 移动
      • 苹果手机
        • 的Index.aspx
      • 黑莓
        • 的Index.aspx
    • 的Index.aspx

我不同意@Mehrdad关于使用自定义视图引擎的看法.视图引擎有多个用途,其中一个目的是查找控制器的视图.您可以通过重写FindView方法来完成此操作.在此方法中,您可以检查查找视图的位置.在您知道哪个设备正在使用您的网站后,您可以使用您提出的策略来组织视图以返回该设备的视图.

public class CustomViewEngine : WebFormViewEngine
{
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        // Logic for finding views in your project using your strategy for organizing your views under the Views folder.
        ViewEngineResult result = null;
        var request = controllerContext.HttpContext.Request;

        // iPhone Detection
        if (request.UserAgent.IndexOf("iPhone",
   StringComparison.OrdinalIgnoreCase) > 0)
        {
            result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
        }

        // Blackberry Detection
        if (request.UserAgent.IndexOf("BlackBerry",
   StringComparison.OrdinalIgnoreCase) > 0)
        {
            result = base.FindView(controllerContext, "Mobile/BlackBerry/" + viewName, masterName, useCache);
        }

        // Default Mobile
        if (request.Browser.IsMobileDevice)
        {
            result = base.FindView(controllerContext, "Mobile/" + viewName, masterName, useCache);
        }

        // Desktop
        if (result == null || result.View == null)
        {
            result = base.FindView(controllerContext, viewName, masterName, useCache);
        }

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码允许您根据策略设置视图.如果没有找到设备的视图或者没有默认的移动视图,则回退是桌面视图.

如果您决定将逻辑放在控制器中而不是创建视图引擎.最好的方法是创建一个自定义ActionFilterAttribute,您可以使用它来装饰控制器.然后覆盖OnActionExecuted方法以确定哪个设备正在查看您的站点.你可以查看这篇博文,了解如何发布.该帖子还有一些很好的链接到这个主题的一些混合视频.