2015-01-23 4 views
1

Использование DisplayModeProvider для выбора между представлениями для «Desktop», «Tablet» и «Phone» в веб-приложении MVC5. Насколько я понимаю, этот класс выбирает правильный провайдер по порядку и использует первого поставщика, который возвращает True. Однако, когда я просматриваю код, я нахожу, что через код повторяется цикл (он проходит много раз, иногда более 10 циклов), прежде чем принимать решение о правильном режиме. Я использую WURFL Cloud для обнаружения устройства. Наконец, я начал кэшировать результаты WURFL в переменной Session. Думаю, что с моим кодом и/или логикой должно быть что-то не так. Это на VB.net, так как это эволюция старого проекта. Первый блок кода находится в Application_Start в global.asax. Прежде чем он был в отдельном классе, но переместил его в global.asax в попытке решить эту проблему.DisplayModeProvider issues

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 

Хотя приложение работает без ошибок, я не могу поверить, велосипед через эту рутину должен происходить. Хотел бы прояснить это, если это возможно. Что я делаю не так? Спасибо заранее!

ответ

1

Как я вижу, проблема больше связана с внутренней реализацией режимов отображения MVC, чем WURFL API. Код, связанный с делегатом режима отображения, возвращается ASP.NET MVC для каждого запроса для визуализации представления, включая частичные представления. Это, очевидно, приводит к нескольким вызовам, выполняемым в WURFL API. Кроме того, API-интерфейс WURFL Cloud требует времени, чтобы ответить, потому что он должен сделать HTTP-запрос в облаке, проанализировать файл cookie и выяснить детали. Облако WURFL заметно медленнее, чем локальный API WURFL, который использует кеш памяти прямого доступа для сбора сведений о пользовательском агенте. Я использовал WURFL и MVC на нескольких веб-сайтах и ​​просто прошел через это. Для большинства таких сайтов мне удалось получить лицензию на месте. Что касается облака, некоторые внутренние кэширования для каждого запроса, возможно, в вашем классе WURFLServiceModel будут полезны, так что вы в конечном итоге сделаете один запрос облака для каждого рендеринга представления. Мне особенно не нравится использование Сессии, но да, это может быть только я. Сессия по-прежнему является приемлемым способом выполнения «внутреннего кэширования», о котором я говорил выше.

+0

Благодарим за отзыв. Фактически я пытался следить за вашими статьями в реализации режимов отображения. Предложите ли вы более подробные предложения по улучшению моей реализации? Кроме того, я понимаю ваши оговорки об использовании сеанса для кеширования. Я постараюсь улучшить эту ситуацию. – maverickbluer1

+0

Еще раз спасибо за ваш комментарий. Хотя это должно было быть очевидно, я полностью игнорировал необходимость частичного просмотра для запуска этого кода. Это полностью объясняет множественные вызовы DisplayModeProvider при прохождении кода. Есть ли у вас какие-либо предложения по более эффективному использованию кеширования, специфичного для сеанса? – maverickbluer1

0

Luca Passani, ScientiaMobile CTO здесь. Я поручил группам поддержки и инженерии связаться с вами в автономном режиме и работать с вами, чтобы добраться до конца проблемы, с которой вы столкнулись. Для администраторов SO. Мы сообщим здесь краткое изложение, когда проблема будет идентифицирована и решена. Благодарю.

+0

Спасибо, но я не думаю, что ошибка, с которой я сталкиваюсь (данный ключ отсутствовал в словаре), с клиентом WURFL cloud напрямую связан с этой проблемой. Я ценю вашу заботу и ваши усилия, чтобы изолировать эту ошибку. – maverickbluer1