Перестали работать мобильные дисплеи ASP.NET MVC 4 - PullRequest
28 голосов
/ 20 февраля 2012

Режимы мобильного отображения в 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
});

Ответы [ 7 ]

21 голосов
/ 15 сентября 2012

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

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

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

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

1 голос
/ 16 июля 2012

Возможно ошибка в ASP.NET MVC 4, связанная с кэшированием представлений, см .:

http://forums.asp.net/p/1824033/5066368.aspx/1?Re+MVC+4+RC+Mobile+View+Cache+bug+

1 голос
/ 04 июля 2012

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

См. http://aspnetwebstack.codeplex.com/workitem/276 для получения дополнительной информации

0 голосов
/ 01 мая 2014

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

Чтобы избежать этой проблемы, вы можете указать 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

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

0 голосов
/ 15 октября 2013

Разве вы не можете просто сделать это?

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.
}
0 голосов
/ 12 марта 2012

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

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

0 голосов
/ 05 марта 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...