使用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
虽然应用程序运行没有错误,但我无法相信应该发生通过此例程的循环。如果可能的话,想清除它。我究竟做错了什么?非常感谢提前!
答案 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管理员。在确定并解决问题时,我们将在此处汇总摘要。谢谢。