Проблемы с 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. Мы сообщим об этом здесь, когда проблема будет выявлена ​​и решена. Благодарю.

Другие вопросы по тегам