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 管理员。确定并解决问题后,我们将在此处报告摘要。谢谢。
使用 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 管理员。确定并解决问题后,我们将在此处报告摘要。谢谢。