Проблемы с регистрацией MVC5 DisplayModeProvider

Поэтому у меня есть приложение MVC 5 с 3 режимами отображения: рабочий стол (по умолчанию), мобильный телефон и планшет. Я использую WURFL, чтобы выяснить устройства. Вот код, вызываемый из global.cs для регистрации:

public static void RegisterDisplayModes(IList<IDisplayMode> displayModes){
        var datafile = HttpContext.Current.Server.MapPath(WurflDataFilePath);
        var configurer = new InMemoryConfigurer().MainFile(datafile);
        var manager = WURFLManagerBuilder.Build(configurer);
        HttpContext.Current.Cache[WURFLMANAGER_CACHE_KEY] = manager;

        bool mobileEnabled = ConfigurationManager.AppSettings["EnableMobileSite"] == "true";
        bool tabletEnabled = ConfigurationManager.AppSettings["EnableTabletSite"] == "true";

        var modeDesktop = new DefaultDisplayMode("") {
                                                        ContextCondition = (c => c.Request.IsDesktop())
                                                    };
        var modeMobile = new DefaultDisplayMode("mobile"){
                                                             ContextCondition = (c => c.Request.IsMobile())
                                                         };
        var modeTablet = new DefaultDisplayMode("tablet"){
                                                             ContextCondition = (c => c.Request.IsTablet())
                                                         };

        displayModes.Clear();
        if (mobileEnabled) displayModes.Add(modeMobile);
        if (tabletEnabled) displayModes.Add(modeTablet);
        displayModes.Add(modeDesktop);
    }

Я использую некоторые методы расширения для HttpRequestBase, как описано в http://msdn.microsoft.com/en-us/magazine/dn296507.aspx:

public static bool IsDesktop(this HttpRequestBase request){
        return true;
    }
    public static bool IsMobile(this HttpRequestBase request) {
        return IsMobileInternal(request.UserAgent) && !IsForcedDesktop(request);
    }
    public static bool IsTablet(this HttpRequestBase request) {
        return IsTabletInternal(request.UserAgent) && !IsForcedDesktop(request);
    }

    public static void OverrideBrowser(this HttpRequestBase request, bool forceDesktop){
        request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY] = forceDesktop;
    }

    public static bool IsForcedDesktop(this HttpRequestBase request){
        var isForced = request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY];
        return isForced != null ? isForced.ToString().ToBool() : false;
    }

    private static bool IsMobileInternal(string userAgent) {
        var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
        if (device.IsTablet() == true) {
            return false;
        } else {
            return device.IsMobile();
        }
    }

    private static bool IsTabletInternal(string userAgent) {
        var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
        return device.IsTablet();
    }

Некоторое время все работает нормально, но через час или около того мобильные и планшетные устройства начинают отображать представления рабочего стола, а представление рабочего стола начинает отображать общее представление ViewSwitcher (я предполагаю, что большинство людей знакомы с ним, оно просто позволяет вам чтобы показать рабочий стол с мобильного устройства). Это почти как та ошибка кеширования в mvc4. Я попытался удалить свой код, чтобы зарегистрировать режимы отображения, и просто пошел с мобильной поддержкой mvc по умолчанию, и он работает нормально, у него та же проблема! Ясно, что где-то здесь есть проблема... кто-нибудь может увидеть что-нибудь очевидное? Почти невозможно отладить, потому что проблемы начинают появляться только через долгое время, и даже тогда только в реальной системе! Есть идеи?

Спасибо, куча... был по этому вопросу слишком долго сейчас... Ура Энди

РЕДАКТИРОВАТЬ: даже удаление его обратно к реализации по умолчанию создает проблему. Я добавил некоторый отладочный код, чтобы убедиться, что я на самом деле запускаю mvc5, но, похоже, так и есть. Я также попробовал изначально рекомендованный способ решения проблемы на mvc4, отключив кэш, но все равно не радуюсь. Неужели нет никого с информацией об этом?

1 ответ

Решение

Вот и я наконец понял это. Очень просто, как обычно. По какой-то причине я использовал RequestContext.HttpContext.Cache для сохранения статуса, когда кто-то хочет получить полный просмотр, а не мобильный просмотр. Я никогда не использовал HttpContext.Cache, я почти уверен, что взял бы это где-нибудь из блога - но больше не могу его найти. Так что все, что произошло, было то, что это изменило бы мнение для всех, а не только для одного человека. Не могу поверить, что потребовались недели, чтобы понять это. Надеюсь, это поможет кому-то еще в какой-то момент.

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