Подтвердить что ты не робот

ASP.NET MVC 4 режима мобильного дисплея перестает работать

Мобильные режимы отображения в ASP.NET MVC 4 перестают обслуживать правильные представления примерно через час безотказной работы, несмотря на то, что браузер переопределяет правильное обнаружение переопределенного мобильного устройства.

Утилизация пула приложений временно решает проблему.

Новая функция переопределения браузера позволяет мобильным устройствам просматривать настольную версию сайта и наоборот. Но примерно через час безотказной работы мобильные представления больше не отображаются для мобильного устройства; визуализируются только стандартные шаблоны Razor для рабочего стола. Единственное исправление заключается в утилизации пула приложений.

Как ни странно, браузерное переопределение cookie продолжает функционировать. Главный шаблон _Layout.cshtml корректно отображает текст "мобильный" или "рабочий стол" в зависимости от значения ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice, но все еще отображаются неверные представления. Это заставляет меня думать, что проблема заключается в DisplayModes.

Действие, о котором идет речь, не кэшируется:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]

Я использую 51Degrees для обнаружения мобильных устройств, но я не думаю, что это должно повлиять на переопределенное обнаружение мобильных устройств. Является ли это ошибкой в ​​ DisplayModes для ASP.NET MVC 4 Beta и Developer Preview, или я делаю что-то еще неправильно?


Вот моя настройка DisplayModes в Application_Start:

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
{
    ContextCondition = context =>
        context.GetOverriddenBrowser().IsMobileDevice
        && (context.Request.UserAgent.IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0
        || context.Request.UserAgent.IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0
        || !context.Request.Browser.IsMobileDevice)
    });

/*  Looks complicated, but renders Home.iPhone.cshtml if the overriding browser is
    mobile or if the "real" browser is on an iPhone or Android. This falls through
    to the next instance Home.Mobile.cshtml for more basic phones like BlackBerry.
*/

DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("Mobile")
{
    ContextCondition = context =>
        context.GetOverriddenBrowser().IsMobileDevice
});
4b9b3361

Ответ 1

Это известная проблема в MVC 4 (Codeplex: # 280: Multiple DisplayModes - ошибка кэширования, будет отображаться неверный вид). Это будет исправлено в следующей версии MVC.

Тем временем вы можете установить обходной пакет, доступный здесь: http://nuget.org/packages/Microsoft.AspNet.Mvc.FixedDisplayModes.

Для большинства приложений просто установка этого пакета должна решить проблему.

Для некоторых приложений, которые настраивают коллекцию зарегистрированных движков просмотра, вы должны убедиться, что вы ссылаетесь на Microsoft.Web.Mvc.FixedRazorViewEngine или Microsoft.Web.Mvc.FixedWebFormViewEngine, вместо версии представления представления по умолчанию.

Ответ 2

У меня была аналогичная проблема, и это оказалось ошибкой при смешивании веб-форм на основе настольных представлений с помощью мобильных представлений на основе бритв.

Подробнее см. http://aspnetwebstack.codeplex.com/workitem/276

Ответ 4

Я не могу говорить об этом конкретном стеке (я все еще в MVC2), но проверьте настройки кэширования вывода (либо в своих контроллерах, либо на представлениях, и в вашем веб-контенте в вашем приложении и на уровне машины). Я видел, как он работает сначала для первых пользователей, а затем браузер для настольных компьютеров поступает именно тогда, когда ASP решает кэшировать, тогда каждый получает одинаковое представление. В результате мы избегали кэширования вывода, надеясь, что это будет рассмотрено позже.

Ответ 5

Если вы хотите, чтобы все мобильные устройства использовали один и тот же мобильный макет, вы можете использовать

DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("Mobile") 
{ 
    ContextCondition = context => 
        context.GetOverriddenBrowser().IsMobileDevice 
}); 

И, конечно же, вам нужно сделать представление в общей папке макета с именем _Layout.Mobile.cshtml

Если вы хотите иметь отдельный макет для каждого типа устройства или браузера, вам нужно это сделать;

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Android")
            {
                ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf
                    ("Android", StringComparison.OrdinalIgnoreCase) >= 0)
            });

            DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
            {
                ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf
                    ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
            });

            DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Mobile")
            {
                ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf
                   ("IEMobile", StringComparison.OrdinalIgnoreCase) >= 0)
            });

И, конечно же, вам нужно сделать представление в общей папке макета для каждого имени

_Layout.Android.cshtml _Layout.iPhone.cshtml _Layout.Mobile.cshtml

Ответ 6

Можете ли вы не просто сделать это?

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    // Code removed for clarity.

    // Cache never expires. You must restart application pool
    // when you add/delete a view. A non-expiring cache can lead to
    // heavy server memory load.

    ViewEngines.Engines.OfType<RazorViewEngine>().First().ViewLocationCache =
        new DefaultViewLocationCache(Cache.NoSlidingExpiration);

    // Add or Replace RazorViewEngine with WebFormViewEngine
    // if you are using the Web Forms View Engine.
}

Ответ 7

Итак, ребята, вот ответ на все ваши заботы.....:)

Чтобы избежать этой проблемы, вы можете проинструктировать ASP.NET о том, чтобы изменить запись в кэше в зависимости от того, использует ли посетитель мобильное устройство. Добавьте параметр VaryByCustom на ваши объявления OutputCache следующим образом:

<%@ OutputCache VaryByParam="*" Duration="60" VaryByCustom="isMobileDevice" %>
Next, define isMobileDevice as a custom cache parameter by adding the following method override to your Global.asax.cs file:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (string.Equals(custom, "isMobileDevice", StringComparison.OrdinalIgnoreCase))
        return context.Request.Browser.IsMobileDevice.ToString();

    return base.GetVaryByCustomString(context, custom);
}

Это гарантирует, что посетители мобильных устройств на странице не получат вывод, ранее помещенный в кеш посетителем рабочего стола.

см. этот технический документ, опубликованный Microsoft.:)

http://www.asp.net/whitepapers/add-mobile-pages-to-your-aspnet-web-forms-mvc-application

Спасибо и продолжайте кодирование.....