次の方法で共有


方法: モバイル ページを ASP.NET Web フォーム / MVC アプリケーションに追加する

適用対象

  • ASP.NET Web Forms バージョン 4.0
  • ASP.NET MVC バージョン 3.0

まとめ

この方法では、ASP.NET Web Forms/MVC アプリケーションからモバイル デバイス用に最適化されたページを提供するさまざまな方法について説明し、広範なデバイスを対象とする場合に考慮すべきアーキテクチャと設計の問題について提案を行います。 また、このドキュメントでは、ASP.NET 2.0 から 3.5 の ASP.NET モバイル コントロールが廃止された理由と、いくつかの最新の代替手段について説明します。

内容

  • 概要
  • アーキテクチャ オプション
  • ブラウザーとデバイスの検出
  • ASP.NET Web Forms アプリケーションがモバイル固有のページを表示する方法
  • ASP.NET MVC アプリケーションがモバイル固有のページを表示する方法
  • その他のリソース

ASP.NET Web Forms と MVC の両方についてこのホワイト ペーパーの手法を実証するダウンロード可能なコード サンプルについては、「ASP.NET を使用したモバイル アプリとサイト」を参照してください。

概要

Web にアクセスする手段として、モバイル デバイス (スマートフォン、フィーチャー フォン、タブレット) の人気は高まり続けています。 このことは、多くの Web 開発者や Web 指向の企業にとって、これらのデバイスを使用する訪問者に優れた閲覧エクスペリエンスを提供することがますます重要であることを意味します。

以前のバージョンの ASP.NET でモバイル ブラウザーがサポートされていた方法

ASP.NET バージョン 2.0 から 3.5 には、ASP.NET モバイル コントロールが含まれています。これは、System.Web.Mobile.dll アセンブリと System.Web.UI.MobileControls 名前空間内のモバイル デバイス用のサーバー コントロールのセットです。 アセンブリは引き続き ASP.NET 4 に含まれていますが、非推奨です。 開発者は、このホワイト ペーパーで説明されているような最新のアプローチに移行することをお勧めします。

ASP.NET モバイル コントロールが古いテクノロジであるとされている理由は、その設計が 2005 年以前に一般的だった携帯電話に由来しているためです。 コントロールは主に、その時代の WAP ブラウザー用に WML または cHTML マークアップ (通常の HTML ではなく) をレンダリングするように設計されています。 しかし、WAP、WML、cHTML は、ほとんどのプロジェクトで使われなくなりました。これは、HTML がモバイル ブラウザーとデスクトップ ブラウザーの両方にとって同様に広く使われるマークアップ言語になったためです。

今日のモバイル デバイス サポートの課題

モバイル ブラウザーで HTML がほぼ一般的にサポートされるようになりましたが、優れたモバイル閲覧エクスペリエンスの創造を目指す場合は、引き続き多くの課題に直面します。

  • 画面サイズ - モバイル デバイスの形状はそれぞれで大きく異なり、多くの場合、画面はデスクトップ モニターよりもはるかに小さくなります。 そのため、完全に異なるページ レイアウトの設計が必要になる場合があります。
  • 入力方法 – 一部のデバイスにはキーパッドがあり、一部にはスタイラスがあり、他のデバイスはタッチを使用します。 場合によっては、複数のナビゲーション メカニズムとデータ入力方法を検討する必要があります。
  • 標準コンプライアンス – 多くのモバイル ブラウザーでは、最新の HTML、CSS、または JavaScript 標準がサポートされていません。
  • 帯域幅 – 携帯データ ネットワークのパフォーマンスは大きく異なり、一部のエンド ユーザーはメガバイト単位で課金されます。

万能のソリューションはありません。アプリケーションでは、アクセスするデバイスに応じて異なる外観と動作が必要になります。 これは、必要なモバイル サポートのレベルに応じて、デスクトップの "ブラウザー戦争" よりも Web 開発者にとって大きな課題になる可能性があります。

モバイル ブラウザーのサポートに初めて取り組む開発者は、最初は最新の最も洗練されたスマートフォン (Windows Phone 7、iPhone、Android など) をサポートすることが重要であると考えることがよくあります。これは、開発者自身がそのようなデバイスを個人的に所有していることが多いためです。 しかし、安価な携帯電話は引き続き非常に人気があり、その所有者はそれらを使用して Web を閲覧します。特に携帯電話がブロードバンド接続よりも簡単に入手できる国や地域ではそのような状況があります。 ビジネスでは、可能性のある顧客を考慮して、サポートするデバイスの範囲を決定する必要があります。 高級ヘルス スパ用のオンライン パンフレットを構築する場合は、最新のスマートフォンのみをターゲットにするようにビジネス上の決定を下すことができます。一方、映画のチケット予約システムを作成する場合は、おそらく、最新ではないフィーチャーフォンを持つ訪問者を考慮する必要があります。

アーキテクチャ オプション

ASP.NET Web Forms または MVC の特定の技術的な詳細に進む前に、Web 開発者には、一般的に、モバイル ブラウザーをサポートするための 3 つの主要なオプションがあることに注意してください。

  1. 何もしない - 単に標準のデスクトップ指向の Web アプリケーションを作成し、モバイル ブラウザーに任せて許容できる範囲でレンダリングできます。

    • 利点: これは、実装および維持のために最もコストがかからないオプションで、余分な作業がありません

    • 欠点: エンドユーザー エクスペリエンスが最悪になります。

      • 最新のスマートフォンでは、デスクトップ ブラウザーと同様に HTML がレンダリングされる場合がありますが、ユーザーは小さな画面でコンテンツを利用するために、水平方向と垂直方向にズームしてスクロールするように強制されます。 これは最適とは言えません。
      • 古いデバイスやフィーチャー フォンでは、満足のいく方法でマークアップをレンダリングできない場合があります。
      • 最新のタブレット デバイス (画面はノート PC の画面と同じ大きさになる場合もあります) でも、さまざまな操作ルールが適用されます。 タッチベースの入力は、大きなボタンとリンクが離れて配置されていると最適に機能し、フライアウト メニューの上にマウス カーソルを置くことはありません。
  2. クライアント上の問題を解決する - CSS とプログレッシブ エンハンスメントを慎重に使用すると、それらを実行している任意のブラウザーに適応するマークアップ、スタイル、スクリプトを作成することができます。 たとえば、CSS 3 メディア クエリでは、選択したしきい値よりも画面が狭いデバイスで 1 列のレイアウトに変わる、複数列のレイアウトを作成できます。

    • 利点: 未知の将来のデバイスであっても、画面や入力の特性に応じて、使用中の特定のデバイス向けにレンダリングを最適化します
    • 利点: すべての種類のデバイスでサーバー側ロジックを簡単に共有でき、コードや作業の重複を最小限に抑えることができます
    • 欠点: モバイル デバイスはデスクトップ デバイスとは大きく異なるため、モバイル ページをデスクトップ ページとは完全に異なるようにして、別の情報が表示されるようにしたい場合があります。 このようなバリエーションは、CSS だけで確実に実現するには非効率的または不可能な場合があり、特に、古いデバイスが CSS ルールを解釈する方法に一貫性がないことを考慮すると困難です。 これは特に CSS 3 属性に当てはまります。
    • 欠点: 異なるデバイスに対するさまざまなサーバー側ロジックとワークフローをサポートしません。 たとえば、CSS のみでモバイル ユーザー向けの簡単なショッピング カート チェックアウト ワークフローを実装することはできません。
    • 欠点: 非効率的な帯域幅の使用。 ターゲット デバイスでは情報のサブセットのみを使用する場合でも、サーバーは、考えられるすべてのデバイスに適用されるマークアップとスタイルを送信する必要がある場合があります。
  3. サーバー上の問題を解決する - サーバーにアクセスしているデバイスや、少なくともそのデバイスの特性 (画面サイズや入力方法、モバイル デバイスかどうかなど) をサーバーが把握している場合、異なるロジックを実行し、異なる HTML マークアップを出力できます。

    • 利点: 最大限の柔軟性。 制限なく、モバイル用にサーバー側ロジックを変更したり、目的のデバイス固有のレイアウトに合わせてマークアップを最適化したりできます。
    • 利点: 効率的な帯域幅の使用。 必要なのは、ターゲット デバイスが使用するマークアップとスタイル情報を送信することだけです。
    • 欠点: 作業やコードの繰り返しが強制される場合があります (たとえば、Web Forms ページまたは MVC ビューの若干異なる類似したコピーを作成する場合など)。 可能であれば、一般的なロジックを基になるレイヤーまたはサービスに取り出しますが、それでも、UI コードまたはマークアップの一部を複製してから並行して維持する必要がある場合があります。
    • 欠点: デバイスの検出が簡単ではありません。 これには、既知のデバイスの種類とその特性 (常に完全に最新であるとは限りません) のリストまたはデータベースが必要であり、すべての受信要求が正確に一致するとは限りません。 このドキュメントでは、後でいくつかのオプションとその落とし穴について説明します。

最良の結果を得るには、ほとんどの開発者はオプション (2) と (3) を組み合わせる必要があることがわかります。 少しのスタイルの違いは、クライアントで CSS または JavaScript を使用して調整するのが最適ですが、データ、ワークフロー、またはマークアップの大きな違いは、サーバー側のコードで実装するのが最も効果的です。

このホワイト ペーパーで取り上げるのはサーバー側の手法

ASP.NET Web Forms と MVC はどちらも主にサーバー側テクノロジであるため、このホワイト ペーパーでは、モバイル ブラウザー用にさまざまなマークアップとロジックを生成できるサーバー側の手法に焦点を当てます。 もちろん、これを任意のクライアント側の手法 (CSS 3 メディア クエリ、プログレッシブ エンハンスメント JavaScript など) と組み合わせることもできますが、これは ASP.NET 開発というよりも Web デザインの問題です。

ブラウザーとデバイスの検出

モバイル デバイスをサポートするためのすべてのサーバー側の手法の主な前提条件は、訪問者が使用しているデバイスを把握することです。 実際には、そのデバイスの製造元とモデル番号を知るよりも、デバイスの特性を知るほうが有用です。 特性には次のものが含まれます。

  • モバイル デバイスかどうか
  • 入力方法 (マウス/キーボード、タッチ、キーパッド、ジョイスティック...)
  • 画面サイズ (物理的およびピクセル単位)
  • サポートされているメディアとデータの形式
  • など

モデル番号よりも特性に基づいて意思決定を行う方が良い理由は、今後登場するデバイスを処理するための準備ができることです。

ASP.NET の組み込みのブラウザー検出使用のサポート

ASP.NET Web Forms と MVC の開発者は、Request.Browser オブジェクトのプロパティを調べることで、アクセスするブラウザーの重要な特性をすぐに検出できます。 たとえば、次を確認します。

  • Request.Browser.IsMobileDevice
  • Request.Browser.MobileDeviceManufacturer、Request.Browser.MobileDeviceModel
  • Request.Browser.ScreenPixelsWidth
  • Request.Browser.SupportsXmlHttp
  • その他多くのツール

バックグラウンドで、ASP.NET プラットフォームは、受信 User-Agent (UA) HTTP ヘッダーを、ブラウザー定義 XML ファイルのセット内の正規表現と照合します。 既定では、プラットフォームには多くの一般的なモバイル デバイスの定義が含まれており、認識させたい他のデバイス用にカスタム ブラウザー定義ファイルを追加できます。 詳細については、ASP.NET の Web サーバー コントロールとブラウザー機能に関する MSDN のページを参照してください。

51Degrees.mobi Foundation を介した WURFL デバイス データベースの使用

ASP.NET の組み込みのブラウザー検出のサポートは、多くのアプリケーションに対応できますが、主に次の 2 つのケースで十分でない場合があります。

  • 最新のデバイスを認識する場合 (ブラウザー定義ファイルを手動で作成せずに)。 .NET 4 のブラウザー定義ファイルは、Windows Phone 7、Android フォン、Opera Mobile ブラウザー、または Apple iPad を認識するには、十分に最近ではないことに注意してください。
  • デバイスの機能に関する詳細情報が必要な場合。 デバイスの入力方法 (タッチかキーパッドかなど)、またはブラウザーでサポートされているオーディオ形式について知る必要がある場合があります。 この情報は、標準のブラウザー定義ファイルには定義されていません。

ワイヤレス ユニバーサル リソース ファイル (WURFL) プロジェクトでは、現在使用されているモバイル デバイスに関する最新の詳細情報が保持されています。

.NET 開発者にとって素晴らしいニュースとして、ASP.NET のブラウザー検出機能は拡張可能であるため、これらの問題を克服するために拡張することができます。 たとえば、オープン ソースの 51Degrees.mobi Foundation ライブラリをプロジェクトに追加できます。 これは、ASP.NET IHttpModule またはブラウザー機能プロバイダー (Web Forms と MVC アプリケーションの両方で使用可能) で、WURFL データを直接読み取って ASP.NET の組み込みのブラウザー検出メカニズムに設定します。 モジュールをインストールすると、Request.Browser には、より正確で詳細な情報が表示されるようになります。以前に説明したデバイスの多くが正しく認識され、その機能が一覧表示されます (入力方法などの追加機能を含む)。 詳細については、プロジェクトのドキュメントを参照してください。

Web Forms アプリケーションでモバイル固有のページを表示する方法

新しい Web Forms アプリケーションが一般的なモバイル デバイスに既定でどのように表示されるかを次に示します。

Screenshot of two Web Forms applications as displayed on Windows Phone 7 and Opera Mobile.

明らかに、どちらのレイアウトもモバイルに対応しているとは言い難く、このページは、小さな縦向きの画面ではなく、大きな横向きのモニター用に設計されています。 ここで何ができるでしょうか?

このホワイト ペーパーで既に説明したように、モバイル デバイス用にページを調整する方法は多数あります。 一部の手法はサーバー ベースであり、他の手法はクライアントで実行されます。

モバイル固有のマスター ページの作成

要件に応じて、すべての訪問者に同じ Web Forms を使用できる場合がありますが、デスクトップ訪問者用とモバイル訪問者用に 2 つの個別のマスター ページを持ちます。 これにより、ページ ロジックを複製することなく、モバイル デバイスに合わせて CSS スタイルシートまたはトップレベル HTML マークアップを柔軟に変更できます。

これは簡単に行うことができます。 たとえば、次のような PreInit ハンドラーを Web Forms に追加できます。

protected void Page_PreInit(object sender, EventArgs e)
{
    if (Request.Browser.IsMobileDevice)
        MasterPageFile = "~/Mobile.Master";
}

次に、アプリケーションの最上位フォルダーに Mobile.Master という名前のマスター ページを作成し、モバイル デバイスが検出された場合にこれが使用されます。 モバイル マスター ページでは、必要に応じてモバイル固有の CSS スタイルシートを参照できます。 デスクトップの訪問者には、モバイルではなく、既定のマスター ページが引き続き表示されます。

独立したモバイル固有の Web Forms の作成

柔軟性を最大限に高めるために、デバイスの種類ごとに個別のマスター ページを用意する以外にもできることがあります。 1 つはデスクトップ ブラウザー用、もう 1 つはモバイル用の、完全に個別の Web Forms ページのセットを 2 つ実装できます。 これは、大きく異なる情報やワークフローをモバイル訪問者に提示する場合に最適です。 このセクションの残りの部分では、このアプローチについて詳しく説明します。

デスクトップ ブラウザー用に設計された Web Forms アプリケーションが既にあると仮定すると、最も簡単な方法は、プロジェクト内に "Mobile" というサブフォルダーを作成し、そこにモバイル ページを構築することです。 サブサイト全体を独自のマスター ページ、スタイル シート、ページで構築するには、他の Web Forms アプリケーションで使用するのと同じ手法を使用できます。 デスクトップ サイト内のすべてのページに、対応するモバイル用ページを必ずしも生成する必要はありません。モバイル訪問者にとって意味のある機能のサブセットを選択できます。

モバイル ページでは、必要に応じて、一般的な静的リソース (画像、JavaScript、CSS ファイルなど) を通常のページと共有できます。 IIS (Web Forms ページの単純なサブフォルダー) でホストされている場合、"Mobile" フォルダーは個別のアプリケーションとしてマークされないため、デスクトップ ページと同じ構成、セッション データ、その他のインフラストラクチャもすべて共有されます。

Note

通常、このアプローチにはコードの重複が伴います (モバイル ページはデスクトップ ページと類似点を共有する可能性があります)、一般的なビジネス ロジックまたはデータ アクセス コードを、共有された基になるレイヤーまたはサービスに取り出すことが重要です。 そうしないと、アプリケーションの作成と保守作業が 2 倍になります。

モバイル訪問者のモバイル ページへのリダイレクト

多くの場合、閲覧セッションの最初の要求 (セッション内の各要求ではなく) でのみモバイル訪問者をモバイル ページにリダイレクトすると便利です。理由は次のとおりです。

  • その後、モバイル訪問者が必要に応じてデスクトップ ページにアクセスすることを簡単に許可できます。マスターページに「デスクトップ バージョン」へのリンクを置くだけです。 この要求はセッションの最初の要求ではなくなったため、訪問者は、モバイル ページにリダイレクトされません。
  • これにより、サイトのデスクトップ要素とモバイル要素の間で共有される動的リソースの要求に干渉するリスクを回避できます (たとえば、サイトのデスクトップ要素とモバイル要素の両方が IFRAME に表示される共通の Web Forms がある場合や、特定の Ajax ハンドラーがある場合など)

これを行うには、リダイレクト ロジックを Session_Start メソッドに配置します。 たとえば、Global.asax.cs ファイルに次のメソッドを追加します。

void Session_Start(object sender, EventArgs e)
{
    // Redirect mobile users to the mobile home page
    HttpRequest httpRequest = HttpContext.Current.Request;
    if (httpRequest.Browser.IsMobileDevice)
    {
        string path = httpRequest.Url.PathAndQuery;
        bool isOnMobilePage = path.StartsWith("/Mobile/", 
                               StringComparison.OrdinalIgnoreCase);
        if (!isOnMobilePage)
        {
            string redirectTo = "~/Mobile/";

            // Could also add special logic to redirect from certain 
            // recognized pages to the mobile equivalents of those 
            // pages (where they exist). For example,
            // if (HttpContext.Current.Handler is UserRegistration)
            //     redirectTo = "~/Mobile/Register.aspx";

            HttpContext.Current.Response.Redirect(redirectTo);
        }
    }
}

モバイル ページを尊重するようにフォーム認証を構成する

フォーム認証では、認証プロセス中および認証プロセス後に訪問者をリダイレクトできる場所についてなんらかの仮定が行われることに注意してください。

  • ユーザーを認証する必要がある場合、フォーム認証は、ユーザーがデスクトップ ユーザーであるかモバイル ユーザーであるかに関係なく、ユーザーをデスクトップ ログイン ページにリダイレクトします (これだけが、1 つのログイン URL という概念を持つため)。 モバイル ログイン ページのスタイルを異なる方法で設定する場合は、モバイル ユーザーを別のモバイル ログイン ページにリダイレクトするようにデスクトップ ログイン ページを拡張する必要があります。 たとえば、デスクトップ ログイン ページのコードビハインドに次のコードを追加します。

    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Ensure that if Forms Authentication forces a mobile user 
            // to log in, we display the mobile login page
            string returnUrl = Request.QueryString["ReturnUrl"];
            if (!String.IsNullOrEmpty(returnUrl) && returnUrl.StartsWith("/Mobile/",
                                                    StringComparison.OrdinalIgnoreCase)) 
            {
                Response.Redirect("~/Mobile/Account/Login.aspx?ReturnUrl=" 
                                  + HttpUtility.UrlEncode(returnUrl));
            }
    
            RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" 
                                            + HttpUtility.UrlEncode(returnUrl);
        }
    }
    
  • ユーザーが正常にログインすると、フォーム認証は既定でデスクトップ ホーム ページにリダイレクトします (これだけが 1 つの既定のページという概念を持つため)。 ログインが成功した後にモバイル ホーム ページにリダイレクトされるように、モバイル ログイン ページを強化する必要があります。 たとえば、モバイル ログイン ページのコードビハインドに次のコードを追加します。

    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Ensure that after logging in, mobile users stay on mobile pages
            string returnUrl = Request.QueryString["ReturnUrl"];
            if (String.IsNullOrEmpty(returnUrl))
            {
                returnUrl = "~/Mobile/";
            }
            LoginUser.DestinationPageUrl = returnUrl;
    
            // (the following line is already present by default)
            RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" 
                                            + HttpUtility.UrlEncode(returnUrl);
        }
    }
    

    このコードは、既定のプロジェクト テンプレートのように、ページに LoginUser というログイン サーバー コントロールがあることを前提としています。

出力キャッシュの操作

出力キャッシュを使用している場合、既定では、デスクトップ ユーザーが特定の URL にアクセスし (これで出力がキャッシュされる)、その後でモバイル ユーザーがキャッシュされたデスクトップ出力を受け取る可能性があることを注意してください。 この警告は、マスター ページをデバイスの種類別に変えるだけの場合にも、デバイスの種類ごとに完全に異なる Web Forms を実装する場合にも適用されます。

この問題を回避するために、訪問者がモバイル デバイスを使用しているかどうかに応じてキャッシュ エントリを変更するように ASP.NET に指示できます。 次のように、VaryByCustom パラメーターをページの OutputCache 宣言に追加します。

<%@ OutputCache VaryByParam="*" Duration="60" VaryByCustom="isMobileDevice" %>

次に、Global.asax.cs ファイルに次のメソッド オーバーライドを追加して、カスタム キャッシュ パラメーターとして isMobileDevice を定義します。

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);
}

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

作業例

これらの手法の実際の使用例を確認するには、このホワイト ペーパーのコード サンプルをダウンロードしてください。 Web Forms サンプル アプリケーションは、モバイル ユーザーを Mobile というサブフォルダー内の一連のモバイル固有のページに自動的にリダイレクトします。 これらのページのマークアップとスタイル設定は、次のスクリーンショットからわかるように、モバイル ブラウザー向けに最適化されています。

Screenshot of two mobile Web Forms applications as displayed on Windows Phone 7 and Opera Mobile.

モバイル ブラウザー用にマークアップと CSS を最適化する方法の詳細については、このドキュメントの後半の「モバイル ブラウザー用のモバイル ページのスタイル設定」セクションを参照してください。

ASP.NET MVC アプリケーションがモバイル固有のページを表示する方法

Model-View-Controller パターンでは、(コントローラー内の) アプリケーション ロジックが (ビュー内の) プレゼンテーション ロジックから切り離されるため、次のいずれかの方法から選択して、サーバー側コードでモバイル サポートを処理できます。

  1. デスクトップ ブラウザーとモバイル ブラウザーの両方で同じコントローラーとビューを使用しますが、デバイスの種類に応じて異なる Razor レイアウトでビューをレンダリングします。 このオプションは、すべてのデバイスで同じデータを表示するが、単に異なる CSS スタイルシートを提供したり、モバイル用にいくつかのトップレベル HTML 要素を変更したりする場合に最適です。
  2. デスクトップ ブラウザーとモバイル ブラウザーの両方に同じコントローラーを使用しますが、デバイスの種類に応じて別のビューをレンダリングします。 このオプションは、エンド ユーザーにほぼ同じデータを表示し、同じワークフローを提供するが、使用しているデバイスに合わせて大きく異なる HTML マークアップをレンダリングする場合に最適です。
  3. デスクトップ ブラウザーとモバイル ブラウザー用に個別の領域を作成し、それぞれに独立したコントローラーとビューを実装します。 このオプションは、さまざまな情報を含み、デバイスの種類に合わせて最適化されたさまざまなワークフローにユーザーに導く、大きく異なる画面を表示する場合に最適です。 一部のコードが繰り返しになる可能性がありますが、一般的なロジックを基になるレイヤーまたはサービスに取り出すことで、それを最小限に抑えることができます。

最初のオプションを選択し、デバイスの種類ごとに Razor レイアウトのみを変更する場合は、非常に簡単です。 _ViewStart.cshtml ファイルを次のように変更するだけです。

@{
    Layout = Request.Browser.IsMobileDevice ? "~/Views/Shared/_LayoutMobile.cshtml"
                                            : "~/Views/Shared/_Layout.cshtml";
}

モバイル デバイス用に最適化されたページ構造と CSS ルールを使用して、_LayoutMobile.cshtml というモバイル固有のレイアウトを作成できるようになりました。

2 番目のオプションを使用して、訪問者のデバイスの種類に応じてまったく異なるビューをレンダリングする場合は、Scott Hanselman のブログ投稿を参照してください。

このホワイト ペーパーの残りの部分では、モバイル訪問者に提供される機能のサブセットを正確に制御できるように、モバイル デバイス用に個別のコントローラーとビューを作成する 3 番目のオプションに焦点を当てています。

ASP.NET MVC アプリケーション内でのモバイル領域の設定

"Mobile" という領域を、通常の方法で既存の ASP.NET MVC アプリケーションに追加できます。ソリューション エクスプローラーでプロジェクト名を右クリックし、[Add à Area]\(領域の追加\) を選択します。 その後、ASP.NET MVC アプリケーション内の他の領域と同様に、コントローラーとビューを追加できます。 たとえば、モバイル エリアに HomeController という新しいコントローラーを追加して、モバイル訪問者のホーム ページとして機能させます。

URL /Mobile がモバイル ホームページに到達することの確認

URL /Mobile を Mobile 領域内の HomeController のインデックス アクションに到達させる場合は、ルーティング構成に 2 つの小さな変更を加える必要があります。 まず、次のコードに示すように、HomeController が Mobile 領域の既定のコントローラーになるように MobileAreaRegistration クラスを更新します。

public override void RegisterArea(AreaRegistrationContext context)
{
    // By default there is no "controller" parameter in the following line. 
    // Add one referencing "Home" as shown.
    context.MapRoute(
        "Mobile_default",
        "Mobile/{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

つまり、"Home" は、暗黙的にモバイル ページの既定のコントローラー名になったため、モバイル ホーム ページは /Mobile/Home ではなく /Mobile に配置されるようになります。

次に、アプリケーションに 2 つ目の HomeController (つまり、既存のデスクトップ用に加えてモバイル用) を追加すると、通常のデスクトップ ホーム ページが壊れることに注意してください。 "'Home' という名前のコントローラーに一致する複数の型が見つかりました" というエラーで失敗します。 これを解決するには、最上位レベルのルーティング構成 (Global.asax.cs) を更新して、あいまいさがあるときにデスクトップ HomeController が優先されるように指定します。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        // Add the namespace of your desktop controllers here
        new[] { "YourApplication.Controllers" } 
    );
}

これでエラーが解消されて、URL http://<使用するサイト>/ はデスクトップのホーム ページに到達し、http://<使用するサイト>/mobile/ はモバイル ホーム ページに到達します。

モバイル訪問者のモバイル領域へのリダイレクト

ASP.NET MVC にはさまざまな機能拡張ポイントがあるため、リダイレクト ロジックを挿入する方法は多数あります。 1 つの適切なオプションは、次の条件が満たされた場合にリダイレクトを実行するフィルター属性 [RedirectMobileDevicesToMobileArea] を作成することです。

  1. これはユーザーのセッションの最初の要求です (つまり、Session.IsNewSession が true に等しい)
  2. 要求はモバイル ブラウザーから送信されます (Request.Browser.IsMobileDevice が true と等しい)
  3. ユーザーがまだモバイル領域のリソースを要求していない (つまり、URL のパス部分が /Mobile で始まらない)

このホワイト ペーパーに含まれるダウンロード可能なサンプルには、このロジックの実装が含まれています。 これは AuthorizeAttribute から派生した承認フィルターとして実装されます。つまり、出力キャッシュを使用している場合でも正常に動作します (そうしないと、デスクトップ訪問者が最初に特定の URL にアクセスした場合、デスクトップ出力がキャッシュされ、その後、後続のモバイル訪問者に提供される可能性があります)。

これはフィルターであるため適用方法を選択できます。次のように、特定のコントローラーとアクションに適用できます。

public class HomeController : Controller
{
    [RedirectMobileDevicesToMobileArea] // Applies just to this action
    public ActionResult Index()
    {
        // ...
    }
}

… または、Global.asax.cs ファイル内のすべてのコントローラーとアクションに MVC 3 グローバル フィルターとして適用できます。

protected void Application_Start()
{
    // (rest of method unchanged)

    // Using "order" value 1 means it will run after unordered filters
    // associated with specific controllers or actions, so the redirection 
    // location can be overridden for specific actions
    GlobalFilters.Filters.Add(new RedirectMobileDevicesToMobileAreaAttribute(), 1);
}

ダウンロード可能なサンプルでは、モバイル領域内の特定の場所にリダイレクトする、この属性のサブクラスを作成する方法も示します。 つまり、次のことができます。

  • モバイル訪問者をモバイル ホームページに既定でリダイレクトするグローバル フィルターを上記のように登録します。
  • また、特別な [RedirectMobileDevicesToMobileProductPage] フィルターを "製品の表示" アクションに適用します。このアクションにより、モバイル訪問者は、要求した製品ページのモバイル バージョンに移動します。
  • また、フィルターの他の特別なサブクラスを特定のアクションに適用し、モバイル訪問者を同等のモバイル ページにリダイレクトします

モバイル ページを尊重するようにフォーム認証を構成する

フォーム認証を使用している場合は、ユーザーがログインする必要があるときに、ユーザーが 1 つの特定の "ログオン" URL (既定では /Account/LogOn) に自動的にリダイレクトされることに注意してください。 これは、モバイル ユーザーがデスクトップの "ログオン" アクションにリダイレクトされる可能性があることを意味します。

この問題を回避するには、モバイル ユーザーをモバイルの "ログオン" アクションに再びリダイレクトするように、ロジックをデスクトップの "ログオン" アクションに追加します。 既定の ASP.NET MVC アプリケーション テンプレートを使用している場合は、AccountController の LogOn アクションを次のように更新します。

public ActionResult LogOn()
{
    string returnUrl = Request.QueryString["ReturnUrl"];
    if ((returnUrl != null) && returnUrl.StartsWith("/Mobile/", 
                               StringComparison.OrdinalIgnoreCase)) 
    {
        return RedirectToAction("LogOn", "Account", 
                                new { Area = "Mobile", ReturnUrl = returnUrl });
    }
    return View();
}

… 次に、モバイル領域の AccountController というコントローラーに、モバイル固有の適切な "ログオン" アクションを実装します。

出力キャッシュの操作

[OutputCache] フィルターを使用している場合は、キャッシュ エントリをデバイスの種類によって強制的に変更する必要があります。 たとえば、次のように記述します。

[OutputCache(Duration = 60, VaryByParam = "*", VaryByCustom = "isMobileDevice")]

次に、Global.asax.cs ファイルに次のメソッドを追加します。

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);
}

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

作業例

これらの手法の実際の使用例を確認するには、このホワイト ペーパーのコードに関連するサンプルをダウンロードしてください。 このサンプルには、上記の方法を使用してモバイル デバイスをサポートするように強化された ASP.NET MVC 3 (リリース候補) アプリケーションが含まれています。

その他のガイダンスと提案

次の説明は、このドキュメントで説明する手法を使用している Web Forms 開発者と MVC 開発者の両方に関連します。

51Degrees.mobi Foundation を使用したリダイレクト ロジックの強化

作成するアプリケーションに対して、このドキュメントに示されているリダイレクト ロジックで十分な場合がありますが、セッションを無効にする必要がある場合や、Cookie を拒否するモバイル ブラウザーでは機能しません (これらはセッションを持つことができません)。これは、特定の要求がその訪問者からの最初の要求かどうかを判別できないためです。

オープンソースの 51Degrees.mobi Foundation で ASP.NET のブラウザー検出の精度を向上させる方法を既に学習しました。 また、Web.config で構成された特定の場所にモバイル訪問者をリダイレクトする機能も組み込まれています。訪問者の HTTP ヘッダーと IP アドレスのハッシュの一時的なログを格納することで、ASP.NET セッション (および Cookie) に依存せずに機能できるため、各要求が特定の訪問者による最初の要求であるかどうかが認識されます。

web.config ファイルの fiftyOne セクションに追加された次の要素は、検出されたモバイル デバイスからページ ~/Mobile/Default.aspx に最初の要求をリダイレクトします。 Mobile フォルダーの下のページへの要求は、デバイスの種類に関係なくリダイレクトされません。 モバイル デバイスが 20 分以上非アクティブになっている場合、デバイスは忘れられ、後続の要求はリダイレクトの目的で新しいものとして扱われます。

<redirect firstRequestOnly="true"
          mobileHomePageUrl="~/Mobile/Default.aspx"
          timeout="20"
          devicesFile="~/App_Data/Devices.dat"
          mobilePagesRegex="/Mobile/" />

詳細については、51degrees.mobi Foundation のドキュメントを参照してください。

Note

ASP.NET MVC アプリケーションでは 51Degrees.mobi Foundation のリダイレクト機能を使用できますが、ルーティング パラメーターの観点やアクションに MVC フィルターを配置するのではなく、プレーン URL の観点からリダイレクト構成を定義する必要があります。 これは、(執筆時点で) 51Degrees.mobi Foundation がフィルターやルーティングを認識しないためです。

トランスコーダーとプロキシ サーバーの無効化

モバイル ネットワーク オペレーターは、モバイル インターネットに対するアプローチについて、おおまかに次の 2 つの目標を持っています。

  1. できるだけ関連性の高いコンテンツを提供する
  2. 限られた無線ネットワーク帯域幅を共有できる顧客の数を最大化する

ほとんどの Web ページは、大きなデスクトップ サイズの画面と高速の固定回線ブロードバンド接続用に設計されているため、多くのオペレーターは、Web コンテンツを動的に変更するトランスコーダーまたはプロキシ サーバーを使用します。 小さい画面 (特に複雑なレイアウトを処理する処理能力がない "フィーチャーフォン" の場合) に合わせて HTML マークアップまたは CSS を変更したり、ページ配信速度を向上させるために画像を再圧縮する (品質が大幅に低下) 可能性があります。

ただし、モバイル最適化バージョンのサイトを作成する作業を行った場合は、ネットワーク オペレーターによるそれ以上の干渉を求めない可能性があります。 任意の ASP.NET Web Forms の Page_Load イベントに次の行を追加できます。

Response.Cache.SetNoTransforms();

または、ASP.NET MVC コントローラーの場合は、そのコントローラー上のすべてのアクションに適用されるように、次のメソッド オーバーライドを追加できます。

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    filterContext.HttpContext.Response.Cache.SetNoTransforms();
}

結果の HTTP メッセージは、コンテンツを変更しないように W3C 準拠のトランスコーダーとプロキシに通知します。 もちろん、モバイル ネットワーク オペレーターがこのメッセージを尊重する保証はありません。

モバイル ブラウザー用のモバイル ページのスタイル設定

どの HTML マークアップの種類が正しく機能するかや、どの Web デザイン手法が特定のデバイスで使いやすさを最大化するかを詳しく説明することは、このドキュメントの範囲を超えています。 信頼性の低い HTML や CSS の配置テクニックを使用せずに、モバイル サイズの画面用に最適化された、十分にシンプルなレイアウトを見つけることは各自の判断で行います。 ただし、言及する価値のある重要な手法の 1 つに、ビューポート メタ タグがあります。

特定の最新のモバイル ブラウザーでは、デスクトップ モニター用の Web ページの表示で、"ビューポート" とも呼ばれる仮想キャンバスにページをレンダリングし (たとえば、仮想ビューポートは、既定で iPhone では 980 ピクセル、Opera Mobile では 850 ピクセル幅)、画面の物理ピクセルに合わせて結果をスケールダウンします。 その後、ユーザーはそのビューポートの周囲でズームしてパンできます。 これには、ブラウザーが目的のレイアウトでページを表示できるという利点がありますが、ユーザーにとって不便なズームとパンを強制するという欠点もあります。 モバイル向けに設計する場合は、ズームや水平スクロールが不要になるように、狭い画面用に設計することをお勧めします。

ビューポートの幅をモバイル ブラウザーに伝える方法は、非標準のビューポート メタ タグを介して行われます。 たとえば、ページの HEAD セクションに次のコードを追加するとします。

<meta name="viewport" content="width=480">

… すると、サポートされるスマートフォン ブラウザーでは、480 ピクセル幅の仮想キャンバスにページがレイアウトされます。 つまり、HTML 要素で幅をパーセンテージで定義すると、既定のビューポートの幅ではなく、この 480 ピクセルの幅に対するパーセンテージで解釈されます。 その結果、ユーザーは水平方向にズームしてパンする必要が少なくなり、モバイル ブラウジング エクスペリエンスが大幅に向上します。

ビューポートの幅をデバイスの物理ピクセルと一致させる場合は、次のように指定できます。

<meta name="viewport" content="width=device-width">

これが正しく機能するためには、要素がその幅を超えるように明示的に強制しないでください (たとえば、width 属性や CSS プロパティを使用)。そうしないと、ブラウザーは大きなビューポートを使用するように強制されます。 非標準ビューポート タグの詳細も参照してください。

ほとんどの最新のスマートフォンは、縦モードでも横モードでも機能する、デュアル オリエンテーションをサポートしています。 そのため、画面の幅をピクセル単位で想定しないことが重要です。 ユーザーがページの表示中にデバイスの向きを変更できるため、画面の幅が固定されているという想定もしないでください。

古い Windows Mobile および Blackberry デバイスは、ページ ヘッダーに次のメタ タグを受け入れて、コンテンツがモバイル用に最適化されていることが通知されるため、変換しないようにします。

<meta name="MobileOptimized" content="width" />
<meta name="HandheldFriendly" content="true" />

その他のリソース

モバイル ASP.NET Web アプリケーションのテストに使用できるモバイル デバイス エミュレーターとシミュレーターの一覧については、「テスト目的で人気のモバイル デバイスをシミュレーションする」ページを参照してください。

クレジット

  • 主な作成者: Steven Sanderson
  • レビュー担当者/追加コンテンツ ライター: James Rosewell、Mikael Söderström、Scott Hanselman、Scott Hunter