web-dev-qa-db-ja.com

ASP.NET MVC4モバイルディスプレイモードが機能しなくなる

ASP.NET MVC 4のモバイル表示モードは、ブラウザーがオーバーライドされたモバイルデバイスを正しく検出しているにもかかわらず、約1時間の稼働時間の後に正しいビューの提供を停止します。

アプリケーションプールをリサイクルすると、一時的に問題が解決します。

新しいブラウザオーバーライド機能により、モバイルデバイスはデスクトップバージョンのサイトを正しく表示でき、その逆も可能です。ただし、約1時間の稼働時間の後、モバイルビューはモバイルデバイス用にレンダリングされなくなります。デフォルトのデスクトップRazorテンプレートのみがレンダリングされます。唯一の修正は、アプリケーションプールをリサイクルすることです。

不思議なことに、ブラウザのオーバーライドCookieは引き続き機能します。マスター__Layout.cshtml_テンプレートは、ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDeviceの値に応じて、「モバイル」または「デスクトップ」テキストを正しく表示しますが、間違ったビューが引き続きレンダリングされます。これは、問題がDisplayModesにあると私に信じさせます。

問題のアクションはキャッシュされていません:

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

私はモバイル検出に51Degreesを使用していますが、これがオーバーライドされたモバイル検出に影響を与えるとは思われません。これはASP.NETMVC 4 Beta&DeveloperPreviewのDisplayModes機能のバグですか、それとも何か間違ったことをしていますか?


_Application_Start_でのDisplayModesの設定は次のとおりです。

_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
});
_
28
Petrus Theron

これはMVC4の既知の問題です(Codeplex: #280:複数のDisplayModes-キャッシュエラー、間違ったビューが表示されます )。これは、MVCの次のバージョンで修正される予定です。

それまでの間、次の場所で利用可能な回避策パッケージをインストールできます: http://nuget.org/packages/Microsoft.AspNet.Mvc.FixedDisplayModes

ほとんどのアプリケーションでは、このパッケージをインストールするだけで問題が解決するはずです。

登録されたビューエンジンのコレクションをカスタマイズする一部のアプリケーションでは、必ず参照する必要がありますMicrosoft.Web.Mvc.FixedRazorViewEngineまたはMicrosoft.Web.Mvc.FixedWebFormViewEngineデフォルトのビューエンジン実装の代わりに。

21
marcind

ビューのキャッシュに関連するASP.NETMVC4のバグの可能性があります。以下を参照してください。

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

1
user1436475

同様の問題があり、Webフォームベースのデスクトップビューとかみそりベースのモバイルビューを混在させるとバグであることが判明しました。

詳細については、 http://aspnetwebstack.codeplex.com/workitem/276 を参照してください。

1
user1501346

この特定のスタックについて話すことはできませんが(私はまだMVC2にいます)、出力キャッシュの設定を確認してください(コントローラーまたはビューのいずれか、およびアプリとマシンレベルのweb.configで)。最初の数人のユーザーで最初に機能し、その後デスクトップブラウザがちょうどその頃に来るのを見ましたASPキャッシュすることを決定すると、全員が同じビューを取得します。出力キャッシュを回避しました結果として、これが後で対処されることを期待しています。

0
hoserdude

すべてのモバイルデバイスで同じモバイルレイアウトを使用する場合は、

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
KenL

あなたはこれをすることができませんか?

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
Lee Englestone

だからここの人はあなたのすべての心配への答えです..... :)

この問題を回避するために、訪問者がモバイルデバイスを使用しているかどうかに応じて、キャッシュエントリを変更するように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);
}

これにより、ページへのモバイル訪問者は、デスクトップ訪問者によって以前にキャッシュに入れられた出力を受け取らないようになります。

マイクロソフトが発行したこのホワイトペーパーを参照してください。 :)

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

おかげで、コーディングを続けてください.....

0
user3591848