1

使用 DisplayModeProvider 在 MVC5 Web 应用程序中的“桌面”、“平板电脑”和“手机”视图之间进行选择。据我了解,此类按顺序选择正确的提供者,并使用第一个返回 True 的提供者。但是,当我单步执行代码时,我发现在决定正确的模式之前,代码中有一个重复的循环(它会经历多次,有时超过 10 个循环)。我正在使用 WURFL Cloud 进行设备检测。最后,我已经开始将 WURFL 结果缓存到 Session 变量中。认为我的代码和/或逻辑一定有问题。它在 VB.net 中,因为它是遗留项目的演变。第一个代码块在 global.asax 的 Application_Start 中。之前它在一个单独的类中,但将其移至全局。

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})

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

这是我正在使用的扩展方法。它们驻留在一个模块中。错误处理代码是在 WURFL 云“感知到”中断后添加的。每个都装饰有以下内容: 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

公共类 WURFLServiceModel

    私有 miSIOS 作为布尔值
    私有 mIsTablet 作为布尔值
    私人电话作为布尔值
    私有 mResponse 作为字符串
    私有 mErrors 作为字典(字符串,字符串)

    Private api_Key As String = "xxxxxxxxxxxxxxxxxxxxxxxxxx"

    Public Sub New(ByVal request As HttpContextBase)
        GetDataByRequest(请求)
    结束子

    公共子GetDataByRequest(上下文作为HttpContextBase)

        暗淡配置 = 新 DefaultCloudClientConfig(api_Key)
        暗淡管理器 = 新 CloudClientManager(config)
        昏暗信息 = manager.GetDeviceInfo(context)
        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

    结束子

    公共只读属性 IsDesktop 作为布尔值
        得到
            返回真
        结束获取
    结束属性

    公共只读属性 IsIOS 作为布尔值
        得到
            返回 mIsIOS
        结束获取
    结束属性

    公共只读属性 IsTablet 作为布尔值
        得到
            返回 mIsTablet
        结束获取
    结束属性

    公共只读属性 IsPhone 作为布尔值
        得到
            返回手机
        结束获取
    结束属性

尽管应用程序运行时没有错误,但我无法相信应该会循环执行此例程。如果可能的话,想清除它。我究竟做错了什么?提前谢谢了!

4

2 回答 2

1

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

于 2015-01-26T14:39:08.787 回答
0

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

于 2015-01-27T14:15:20.210 回答