DisplayModeProvider 问题

DisplayModeProvider issues

使用 DisplayModeProvider 在 MVC5 网络应用程序中选择 "Desktop"、"Tablet" 和 "Phone" 的视图。据我了解,此 class 按顺序选择正确的提供程序并使用 returns True 的第一个提供程序。然而,当我单步执行代码时,我发现在决定正确的模式之前,代码有一个重复的循环(它经过多次,有时超过 10 个循环)。我正在使用 WURFL Cloud 进行设备检测。最后,我开始在 Session 变量中缓存 WURFL 结果。认为我的代码 and/or 逻辑一定有问题。它在 VB.net 中,因为它是遗留项目的演变。第一个代码块在 global.asax 中的 Application_Start 中。之前它在单独的 class 中,但为了解决这个问题而将其移动到 global.asax。

DisplayModeProvider.Instance.Modes.Clear()
DisplayModeProvider.Instance.Modes.Add(New DefaultDisplayMode("Phone") With {.ContextCondition = Function(c) c.Request.IsPhone})
DisplayModeProvider.Instance.Modes.Add(New DefaultDisplayMode("Tablet") With {.ContextCondition = Function(c) c.Request.IsTablet})
DisplayModeProvider.Instance.Modes.Add(New DefaultDisplayMode("") With {.ContextCondition = Function(c) c.Request.IsDesktop})

我的理解是函数会检查每个上下文条件并在第一个为真时停止。但是,如上所述,即使其中一个函数 returns True,代码也会重复执行。

这是我正在使用的扩展方法。它们驻留在一个模块中。错误处理代码是在 WURFL 云 "perceived" 中断后添加的。每个都装饰有以下内容:System.Runtime.CompilerServices.Extension

Public Function IsPhone(request As HttpRequestBase) As Boolean
    Dim ans As Boolean
    Try
        If Not HttpContext.Current.Session("IsPhone") Is Nothing Then
            ans = HttpContext.Current.Session("IsPhone")
        Else
            wsm = New WURFLServiceModel(New     HttpContextWrapper(HttpContext.Current))
            ans = wsm.IsPhone
            HttpContext.Current.Session("IsPhone") = ans
        End If
    Catch ex As Exception
        ...
    End Try
    Return ans
End Function

Public Function IsTablet(request As HttpRequestBase) As Boolean
    Dim ans As Boolean
    Try
        If Not HttpContext.Current.Session("IsTablet") Is Nothing Then
            ans = HttpContext.Current.Session("IsTablet")
        Else
            wsm = New WURFLServiceModel(New HttpContextWrapper(HttpContext.Current))
            ans = wsm.IsTablet
            HttpContext.Current.Session("IsTablet") = ans
        End If
    Catch ex As Exception
        ...
    End Try
    Return ans
End Function

Public Function IsDesktop(request As HttpRequestBase) As Boolean
    Return True
End Function

这是 WURFLServiceModel 的代码

进口 ScientiaMobile.WurflCloud.Device

Public Class WURFLServiceModel

    私有 mISIOS 作为布尔值
    私有 mIsTablet 作为布尔值
    私有 mIsPhone 作为布尔值
    私有 mResponse 作为字符串
    私人错误作为字典(字符串,字符串)

    私有 api_Key 作为字符串 = "xxxxxxxxxxxxxxxxxxxxxxxxxx"

    Public Sub New(ByVal 请求作为 HttpContextBase)
        GetDataByRequest(请求)
    结束子

    Public Sub GetDataByRequest(上下文作为 HttpContextBase)

        昏暗的配置=新的DefaultCloudClientConfig(api_Key)
        Dim manager = New CloudClientManager(配置)
        模糊信息 = manager.GetDeviceInfo(上下文)
        mIsIOS = info.Capabilities("is_ios")
        mIsPhone = info.Capabilities("is_smartphone")
        mIsTablet = info.Capabilities("is_tablet")
        mBrandName = info.Capabilities("brand_name")
        mModelName = info.Capabilities("model_name")
        mErrors = info.Errors
        mResponse = info.ResponseOrigin

    结束子

    Public ReadOnly 属性 IsDesktop As Boolean
        得到
            Return 正确
        结束获取
    结束 属性

    Public ReadOnly 属性 IsIOS As Boolean
        得到
            Return mIsIOS
        结束获取
    结束 属性

    Public ReadOnly 属性 IsTablet As Boolean
        得到
            Return mIsTablet
        结束获取
    结束 属性

    Public ReadOnly 属性 IsPhone As Boolean
        得到
            Return mIsPhone
        结束获取
    结束 属性

虽然应用程序运行没有错误,但我不敢相信循环执行此例程。如果可能的话,想把它清理干净。我究竟做错了什么?非常感谢!

在我看来,与 WURFL API 相比,这个问题更多地与 MVC 显示模式的内部实现有关。 ASP.NET MVC 为每个渲染视图(包括部分视图)的请求回调绑定到显示模式委托的代码。这显然会导致对 WURFL API 进行多次调用。此外,WURFL 云 API 需要一段时间才能响应,因为它必须向云发出 HTTP 请求、解析 cookie 并找出详细信息。 WURFL Cloud 明显比本地 WURFL API 慢,后者使用直接访问内存缓存来获取用户代理的详细信息。我在许多网站中使用过 WURFL 和 MVC,并且刚刚经历了这个。对于大多数此类站点,我设法获得了内部部署许可证。至于云,您的 WURFLServiceModel class 中的一些按请求的内部缓存可能会有所帮助,这样您最终会为视图的每个渲染发出一个云请求。我不是特别喜欢使用 Session,但是是的,这可能只是我。会话仍然是执行我上面建议的 "internal caching" 的一种可接受的方式。

这里是 ScientiaMobile 的首席技术官 Luca Passani。我指示支持和工程团队离线与您联系并与您一起解决您遇到的问题。对于 SO 管理员。确定并解决问题后,我们将在此处报告摘要。谢谢。