テスターですが何か?

ホビープログラマ略してHPです

ASP.NET MVC4 DP でiOSとAndoindがモバイルデバイスと判定されない?(2)

leave a comment »

以前、ASP.NET MVC4 Developer Preview機能の検証でこちら(【日本語訳】ASP.NET MVC4 Mobile Features Part3 Viewの新機能)のエントリーを公開しました。その際、Android用のViewを作成したのですが、実機のAndroidでアクセスしてもモバイルデバイスとは判定されませんでした。あの時はとりあえずチュートリアルを消化していくことが目的だったので深くは踏み込んでいませんが、ASP.NET4の目玉の新機能がなぜ正しく動作しなかったのかを検証していきます。

検証はモバイルデバイスの判定機能「Viewのオーバーライド」と「ViewSwitcher」を対象にします。「Viewのオーバーライド」については前回のエントリーで検証済みなので、今回は ViewSwitcher を対象にします。

ViewSwitcher

ViewSwitcherとはモバイル用ViewとPC用Viewを切り替える機能です。スマートフォンでページへアクセスすると時々表示される「スマートフォン用さいとはこちら」のような機能です。

まずはjQuery.Mobile.MVC NuGetパッケージを使用してjQueryMobileとview-switcher ウィジェットをインストールします。Package Manager Consoleから「install-Package jQuery.Mobile.MVC」と入力します。

PM> install-Package jQuery.Mobile.MVC
Attempting to resolve dependency ‘AspNetMvc (≥ 4.0.0.0)’.
Attempting to resolve dependency ‘AspNetWebPagesCore (≥ 2.0.10906.0)’.
Attempting to resolve dependency ‘MicrosoftWebInfrastructure (≥ 1.0.0.0)’.
Attempting to resolve dependency ‘jQuery.mobile (≥ 0.5.3)’.
Attempting to resolve dependency ‘jquery (≥ 1.6)’.
Successfully installed ‘jQuery 1.6.4’.
Successfully installed ‘jquery.mobile 0.5.3’.
Successfully installed ‘jQuery.Mobile.MVC 0.0.2’.
Successfully removed ‘jQuery 1.6.2’ from MVC4DPMobileDevice.
Successfully added ‘jQuery 1.6.4’ to MVC4DPMobileDevice.
Successfully added ‘jquery.mobile 0.5.3’ to MVC4DPMobileDevice.
Successfully added ‘jQuery.Mobile.MVC 0.0.2’ to MVC4DPMobileDevice.
Successfully uninstalled ‘jQuery 1.6.2’.

jQuery.Mobile.MVCをインストールすると、モバイル用レイアウトファイル「_Layout.Mobile.cshtml」とViewSwitcher用ファイル「_ViewSwitcher.cshtml」が作成されます。

_ViewSwitcher.cshtml

@if (Request.Browser.IsMobileDevice && Request.HttpMethod == "GET")
{
    <div class="view-switcher ui-bar-a">
        @if (ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)
        {
            @: Displaying mobile view
            @Html.ActionLink("Desktop view", "SwitchView", "ViewSwitcher", new { mobile = false, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
        } 
        else 
        {
            @: Displaying desktop view
            @Html.ActionLink("Mobile view", "SwitchView", "ViewSwitcher", new { mobile = true, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
        }
    </div>
}

そして、前回のエントリーで作成したAndroid,iOS用のビューの名前を変更してそれぞれ「Index.Android.cshtml.hide」、「Index.iPod.cshtml.hide」にリネームします。「Index.Android.cshtml.hide」をコピーしてモバイル用のビュー「Index.Mobile.cshtml」を作成します。そして、Global.asax.csのApplication_Startメソッドから前回追加したコードをコメントアウトした後、Android,iOSからのアクセスの場合にモバイル用のレイアウト、ビューが表示されるようにします。Index, Layoutファイルに対して、モバイルなのかそうではないのか分かるように少しソースを変更します。それぞれのファイルの内容(抜粋)は以下のとおりです。

Index.cshtml(抜粋)

<h3>This is a page for FullBrowser<br />
@Request.UserAgent<br />
@Request.Browser.IsMobileDevice.ToString()
</h3>

Index.Mobile.cshtml(抜粋)

<h3>This is a page for Mobile<br />
@Request.UserAgent<br />
@Request.Browser.IsMobileDevice.ToString()
</h3>

_Layout.cshtml(抜粋)

                <div class="float-left">
                    <p class="site-title">@Html.ActionLink("Not Mobile Layout", "Index", "Home")</p>
                </div>

_Layout.Mobile.cshtml(抜粋)

    <div data-role="page" data-theme="a">
        @Html.Partial("_ViewSwitcher")

        <div data-role="header">
            <h1>Mobile Layout</h1>
        </div>

        <div data-role="content">
            @RenderSection("featured", false)
            @RenderBody()		
        </div>

    </div>

Global.asax.cs Application_Startメソッド

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            DisplayModes.Modes.Insert(0, new DefaultDisplayMode("Mobile")
            {
                ContextCondition = (ctx => ctx.Request.UserAgent.IndexOf(
                                    "Android", StringComparison.OrdinalIgnoreCase) >= 0 ||
                                    ctx.Request.UserAgent.IndexOf(
                                    "iPod", StringComparison.OrdinalIgnoreCase) >= 0)
            });
        }

では、Android,iOS端末からアクセスしてみましょう。結果は以下のようになりました。

Android 2.3(sh-12c)

A3

iOS(iPodtouch)

i3

AndroidとiOSの画面キャプチャーを見れば分かると思いますが、ちょっとおかしいですよね。

Android

  • モバイル用のレイアウトが使用されているが、ビューはモバイル用のものが使用されていない
  • ViewSwitcherが表示されていない(Request.Browser.IsMobileDevice の値がfalseなのでそもそもモバイルデバイスと判定されていない?)

iOS

  • モバイル用のレイアウトが使用されているが、ビューはモバイル用のものが使用されていない

前回のエントリーでちゃんとできていたのに、何で今できないのか意味不明です。AzureのWebロールのインスタンスの中を覗くと「Index.Mobile.cshtml」がありません。なんども発行(Accerlator for WebRole)してもファイルがコピーされませんでした、拡張子を1回別のものに変えたからかもしれません。

image

手動で「Index.Mobile.cshtml」をコピーしてもう一度アクセスしてみます。

Android 2.3(sh-12c)

A4

iOS5(iPod touch)

i4

はい、ちゃんとモバイル用のビューが表示されました。

エントリーが長くなってしまったので、一旦締めます。今回作成したソースはこちらで公開しています、「MVC4DPMobileDeviceCloud_2.zip」をダウンロードしてください。

まとめ

  • Androidがモバイル端末と判断されず、ViewSwitcherが表示されない
  • cshtmlの拡張子を変更後再度拡張子をcshtmlに戻すと、そのファイルが発行対象にならなくなる?

次のエントリーでは、この2点の検証を行います。

Written by david9142

2011年12月31日 @ 10:15 PM

カテゴリー: ASP.NET MVC

Tagged with ,

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。