关于asp.net mvc:DisplayModeProvider问题

DisplayModeProvider issues

使用DisplayModeProvider在MVC5 Web应用程序中的"桌面"、"平板电脑"和"电话"视图之间进行选择。据我所知,此类按顺序选择正确的提供程序,并使用返回true的第一个提供程序。但是,当我单步执行代码时,我发现在决定正确的模式之前,代码中有一个重复的循环(它经过多次,有时超过10个循环)。我正在使用wurfl云进行设备检测。最后,我已经开始在会话变量中缓存wurfl结果。我想我的代码和/或逻辑肯定有问题。它在vb.net中,因为它是一个遗留项目的进化。第一个代码块在global.asax中的application_start中。以前它是在一个单独的类中,但为了解决这个问题,把它移到了global.asax。

1
2
3
4
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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

这是WurfselServiceModel的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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

尽管应用程序运行时没有错误,但我不能相信应该发生这种循环。如果可能的话,我想把它清理干净。我做错什么了?非常感谢!


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


卢卡·帕萨尼,科学移动首席技术官。我指示支持和工程团队离线与您联系,并与您合作,以解决您遇到的问题。对于SO管理员。我们将在发现并解决问题后在此报告摘要。谢谢。