Проблемы с DisplayModeProvider
Использование DisplayModeProvider для выбора между представлениями "Рабочий стол", "Планшет" и "Телефон" в веб-приложении MVC5. Насколько я понимаю, этот класс выбирает правильный поставщик по порядку и использует первый поставщик, который возвращает True. Однако, когда я перебираю код, я обнаруживаю повторяющийся цикл в коде (он проходит несколько раз, иногда в течение 10 циклов), прежде чем выбрать правильный режим. Я использую WURFL Cloud для обнаружения устройств. Наконец, я начал кэшировать результаты WURFL в переменной Session. Думаю, что-то не так с моим кодом и / или логикой. Это на VB.net, так как это развитие унаследованного проекта. Первый блок кода находится в Application_Start в global.asax. Прежде он был в отдельном классе, но переместил его в 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
Импортирует ScientiaMobile.WurflCloud.Device Открытый класс WURFLServiceModel Частные MISIOS As Boolean Частный mistablet As Boolean Частный миссфон как логическое Частный ответ как строка Частные ошибки как словарь (из строки, строки) Private api_Key As String = "xxxxxxxxxxxxxxxxxxxxxxxxxx" Public Sub New(запрос ByVal As HttpContextBase) GetDataByRequest(запрос) End Sub Public Sub GetDataByRequest(контекст как HttpContextBase) Dim config = New DefaultCloudClientConfig(api_Key) Dim manager = New CloudClientManager(config) Dim info = 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("имя_модели") mErrors = info.Errors mResponse = info.ResponseOrigin End Sub Открытое свойство ReadOnly IsDesktop As Boolean Получить Верните True Конец получить Конечная недвижимость Открытое свойство ReadOnly IsIOS As Boolean Получить Возврат МИСИОС Конец получить Конечная недвижимость Открытое свойство ReadOnly IsTablet As Boolean Получить Возврат mIsTablet Конец получить Конечная недвижимость Открытое свойство ReadOnly IsPhone As Boolean Получить Возврат мсфона Конец получить Конечная недвижимость
Хотя приложение работает без ошибок, я не могу поверить, что циклическое выполнение этой процедуры должно происходить. Хотелось бы прояснить это, если это возможно. Что я делаю неправильно? Спасибо заранее!
2 ответа
На мой взгляд, проблема больше связана с внутренней реализацией режимов отображения MVC, чем с WURFL API. Код, связанный с делегатом режима отображения, вызывается ASP.NET MVC для каждого запроса на отображение представления, включая частичные представления. Это, очевидно, приводит к тому, что к WURFL API делается несколько вызовов. Кроме того, облачному API WURFL требуется некоторое время, чтобы ответить, потому что он должен сделать HTTP-запрос к облаку, проанализировать cookie и выяснить детали. Облако WURFL явно медленнее, чем локальный API WURFL, который использует кэш-память прямого доступа для сбора сведений о пользовательском агенте. Я использовал WURFL и MVC на нескольких веб-сайтах и только что прошел через это. Для большинства таких сайтов мне удалось получить локальную лицензию. Что касается облака, было бы полезно некоторое внутреннее кэширование по запросу, возможно, в вашем классе WURFLServiceModel, чтобы в конечном итоге вы сделали один облачный запрос для каждой визуализации представления. Мне не особенно нравится использование Session, но да, это может быть только я. Сессия по-прежнему является приемлемым способом "внутреннего кеширования", которое я предлагал выше.
Лука Пассани, технический директор ScientiaMobile здесь. Я дал указание командам технической поддержки и технической поддержки обратиться к вам в автономном режиме и поработать с вами, чтобы решить проблему, с которой вы столкнулись. Для администраторов SO. Мы сообщим об этом здесь, когда проблема будет выявлена и решена. Благодарю.