しばやん雑記

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

ASP.NET MVC 4 の Display Mode を使って多言語対応を試してみた

ASP.NET MVC 4 というか Web Pages 2 で追加された Display Mode ですが、一般的にはスマートフォンやその他デバイス向けにビューを切り替えるために使われることが多いと思います。

しかし、今回はデバイスの種類ではなく、ブラウザの言語設定にしたがってビューを切り替えて、多言語への対応を行ってみます。その為に IDisplayMode インターフェースを実装した LocalizableDisplayMode クラスを実装しました。

public class LocalizableDisplayMode : IDisplayMode
{
    public bool CanHandleContext(HttpContextBase httpContext)
    {
        return true;
    }

    public DisplayInfo GetDisplayInfo(HttpContextBase httpContext, string virtualPath, Func<string, bool> virtualPathExists)
    {
        var transformedFilename = TransformPath(virtualPath, Thread.CurrentThread.CurrentCulture.Name);

        if (transformedFilename != null && virtualPathExists(transformedFilename))
        {
            return new DisplayInfo(transformedFilename, this);
        }

        return null;
    }

    public string DisplayModeId { get { return "Localizable"; } }

    private string TransformPath(string virtualPath, string suffix)
    {
        if (string.IsNullOrEmpty(suffix))
        {
            return virtualPath;
        }

        var extension = Path.GetExtension(virtualPath);

        return Path.ChangeExtension(virtualPath, suffix + extension);
    }
}

やっていることは単純で、現在のスレッドのカルチャの名前を Display Mode で使うビュー名のサフィックスにしているだけです。

つまり、以下のようなビューを定義することになります。

  • Index.cshtml
    • デフォルトのビュー
  • Index.ja-JP.cshtml
    • 日本語で書かれたビュー
  • Index.de-DE.cshtml
    • ドイツ語で書かれたビュー

作成した Display Mode を使うためには、今までと同じように Global.asax.cs などで DisplayModeProvider に対して登録する必要があります。

// 多言語対応の Display Mode を使う
DisplayModeProvider.Instance.Modes.Insert(0, new LocalizableDisplayMode());

そして、ASP.NET がブラウザの言語設定にしたがってスレッドのカルチャを切り替えるようにするために、Web.config に以下のような設定を追加します。

<system.web>
  <!-- ブラウザの言語設定を見てカルチャを切り替える -->
  <globalization culture="auto" uiCulture="auto" />
</system.web>

これで準備が完了したので、ブラウザの言語設定を切り替えて試してみました。

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

Internet Explorer は日本語、Google Chrome はドイツ語を優先言語として設定してありますが、同じ URL で別々の言語が表示されていますね。

この方法の欠点としては別の Display Mode との共存が出来ないことです。なのでスマートフォンへの対応が必要ない、完全に PC 向けのページなら対応可能かと思います。