しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET MVC 4 のブラウザオーバーライド設定の保存先をカスタマイズする

ASP.NET MVC 4 のブラウザオーバーライドを JavaScript から設定する - しばやん雑記 で ASP.NET MVC 4 というか Web Pages 2 のブラウザオーバーライド機能はクッキーを使って実装されていると紹介しましたが、実はこの User-Agent を保存する部分は開発者が自由に変更することが可能です。

ブラウザオーバーライド設定の保存は BrowserOverrideStores クラスの Current プロパティにセットされているストアが使われるようになっていて、デフォルトで有効になっているのは CookieBrowserOverrideStore クラスなので、クッキーに保存されているという訳です。

// null をセットするとブラウザオーバーライド自体が無効になる
BrowserOverrideStores.Current = null;

ちなみに、上記の例のように BrowserOverrideStores.Current プロパティに null をセットすると、この機能自体が無効になります。

とりあえず、今回は簡単な例として mobile というクエリ文字列が付いている場合にはモバイル版ページを表示するストアを作成してみます。

public class CustomBrowserOverrideStore : BrowserOverrideStore
{
    private const string DesktopUserAgent = "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)";
    private const string MobileUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 8.12; MSIEMobile 6.0)";

    public override string GetOverriddenUserAgent(HttpContextBase httpContext)
    {
        return httpContext.Request.QueryString["mobile"] != null ? MobileUserAgent : DesktopUserAgent;
    }

    public override void SetOverriddenUserAgent(HttpContextBase httpContext, string userAgent)
    {
    }
}

単純に mobile というクエリ文字列がある場合にはモバイル用の User-Agent を、それ以外はデスクトップ用の User-Agent を返すようにしているだけです。ブラウザオーバーライドは User-Agent ベースで実装されているので、2 種類の UA を切り替え用に定数として持っています。

このストアを Global.asax.cs で設定して、実行すると以下のような感じです。ちゃんとクエリ文字列の有無でビューが切り替わっていますね。

f:id:shiba-yan:20130516212509p:plain

この例では SetOverriddenUserAgent は使っていないのですが、実装としては引数で指定された userAgent の値を、次回以降のリクエストでも使えるように保存するだけです。

もう一つ例として、クッキーではなくセッションに保存するストアを作成してみます。

public class SessionBrowserOverrideStore : BrowserOverrideStore
{
    internal static readonly string BrowserOverrideSessionName = ".ASPXBrowserOverride";

    public override string GetOverriddenUserAgent(HttpContextBase httpContext)
    {
        return (string)httpContext.Session[BrowserOverrideSessionName];
    }

    public override void SetOverriddenUserAgent(HttpContextBase httpContext, string userAgent)
    {
        httpContext.Session[BrowserOverrideSessionName] = userAgent;
    }
}

これはもはや説明は要らないですよね。セッションに User-Agent を保存して、読み込んでいるだけのコードです。

今回のストアはブラウザオーバーライドを行うには C# 側からメソッドを呼び出す必要があります。クッキーの場合はクライアント側で完結していましたが、ちょっとめんどくさいですね。

public ActionResult SwitchMobile()
{
    // モバイルの UA に切り替える
    HttpContext.SetOverriddenBrowser(BrowserOverride.Mobile);

    return RedirectToAction("Index");
}

こんな感じでアクションなどの HttpContext に触れる部分で、SetOverriddenBrowser 拡張メソッドを呼び出すと切り替えが可能です。

実際に実行すると以下のような感じです。

f:id:shiba-yan:20130516214343p:plain

最初の例のように、パラメータは付いていませんがセッションに格納しているので、モバイル版が表示されています。

ASP.NET MVC 4 というか Web Pages 2 のブラウザオーバーライド機能は柔軟にカスタマイズが可能なので、例えば既存のサイトがちょっと変わった設定の保存方法を使っていても、MVC 側で吸収することも可能ですね。