DisplayModeProvider问题

时间:2015-01-23 17:52:56

标签: asp.net-mvc vb.net wurfl displaymode

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

我的理解是函数会检查每个上下文条件并在第一个为真的时候停止。但是,如上所述,代码重复执行,即使其中一个函数返回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的代码

Imports ScientiaMobile.WurflCloud.Device

Public Class WURFLServiceModel

    Private mIsIOS As Boolean
    Private mIsTablet As Boolean
    Private mIsPhone As Boolean
    Private mResponse As String
    Private mErrors As Dictionary(Of String, String)

    Private api_Key As String = "xxxxxxxxxxxxxxxxxxxxxxxxxx"

    Public Sub New(ByVal request As HttpContextBase)
        GetDataByRequest(request)
    End Sub

    Public Sub GetDataByRequest(context As HttpContextBase)

        Dim config = New DefaultCloudClientConfig(api_Key)
        Dim manager = New CloudClientManager(config)
        Dim info = 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

    End Sub

    Public ReadOnly Property IsDesktop As Boolean
        Get
            Return True
        End Get
    End Property

    Public ReadOnly Property IsIOS As Boolean
        Get
            Return mIsIOS
        End Get
    End Property

    Public ReadOnly Property IsTablet As Boolean
        Get
            Return mIsTablet
        End Get
    End Property

    Public ReadOnly Property IsPhone As Boolean
        Get
            Return mIsPhone
        End Get
    End Property

虽然应用程序运行没有错误,但我无法相信应该发生通过此例程的循环。如果可能的话,想清除它。我究竟做错了什么?非常感谢提前!

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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