ASP.NET の IE10 対応について

こんにちは。d99 です。  
今回は下記の件を取り上げます。

問題
ASP.NET 4.0 までのバージョンでは、ユーザーエージェント解析に問題があり、Internet Explorer 10 の判定に失敗します。その結果、IE10 に対してだけ JavaScript が出力されずクライアントスクリプトが正常に動作しなかったり、CSS が出力されずレイアウトが崩れたり、といった問題が発生します。

ASP.NET が Internet Explorer 10 の検出に失敗する
https://msdn.microsoft.com/ja-jp/library/ie/hh869299(v=vs.85).aspx

原因
ASP.NET のバグです。

対処
緊急修正モジュールのご用意があります。

ASP.NET 4.0 用
https://support.microsoft.com/kb/2600088

ASP.NET 2.0、3.0 3.5 用
https://support.microsoft.com/kb/2600100
https://support.microsoft.com/kb/2608565

備考
このバグは、所謂 WebFrom にだけ影響し、ASP.NET MVC や ASP.NET WebPages (Razor) には影響しません。

 

今回は上記の問題の、緊急修正モジュール以外の対処についてご紹介します。

この問題については以下の4つの対処方法があります。

  1. 緊急修正モジュール(hotfix)を適用する
  2. セキュリティパッチ(MS11-100)を適用する
  3. 手動でシステムのブラウザ定義を書き換える
  4. アプリケーションに IE10 対応のブラウザ定義を加える

1. は、 既にご紹介した通りです。緊急修正モジュールは ASP.NET のコアモジュールである System.Web.dll 等のバージョンを更新し、ブラウザ定義ファイル ie.browser 等も IE10 に対応した新しいものに更新します。

2. は、 セキュリティパッチに IE10 対応の修正が含まれています。そのため Windows Update で適用されており、問題が発生しなくなっているかもしれません。ただ、これは 1. とは少し異なった修正のため注意が必要です。これについて解説します。

ASP.NET のブラウザ定義ファイルは %windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers などの、.NET Framework インストールフォルダの CONFIG/Browsers サブフォルダにあります。

しかし、ASP.NET は既定ではこのファイル自体を使ってはいません。

ASP.NET はブラウザ判定ルーチンを System.Web.dll の中に持っており、既定ではそれを使っています。上記パスのブラウザ定義ファイルは既定のブラウザ判定ルーチンの内容を示したもので、これをテキストエディタで書き換えただけではそれが反映されません。

反映するためには、aspnet_regbrowsers.exe というツールを使って、上記フォルダの .browser ファイルから判定ルーチンを含む dll を自動生成し、それを GAC にインストールして、既定の判定ルーチンを置き換える必要があります。実際には 「aspnet_regbrowsers.exe  /i」 というコマンドでそれらを全て自動で行いますが、その際に裏で行われているのはそういった動作です。

ASP.NET ブラウザ登録ツール (Aspnet_regbrowsers.exe)
https://msdn.microsoft.com/ja-jp/library/ms229858(v=vs.80).aspx

1. の緊急修正モジュールは、System.Web.dll を更新するので、既定の判定ルーチンが置き換わります。さらにシステムのブラウザ定義ファイル、ie.browser ファイルを更新します。そのため、適用後に aspnet_regbrowsers /i しても修正は維持されます。

しかし、2. の MS11-100 は Sysytem.Web.dll を更新して既定のルーチンは置き換えますが、ブラウザ定義ファイルは IE10 対応に更新されていません。そのため、aspnet_regbrowsers.exe コマンドを実行して既定の判定ルーチンを置き換えてしまっていたり、後に置き換えてしまったりすると、更新されていない ie.browser ファイルによって既定の判定ルーチンが上書きされてしまい、修正が機能しなくなってしまうため注意が必要です。

既定のルーチンを置き換えてしまった場合は、aspnet_regbrowsers.exe /u コマンドで既定の状態 (Sysytem.Web.dll 内のルーチンを使う状態) に戻せます。

3. は、 手動でシステムのブラウザ定義ファイルを置き換える方法です。別のテスト環境等に緊急修正モジュールを適用し、それによって更新された ie.browser ファイルを手に入れます。それを用いて、ターゲット環境の ie.browser を書き換え、aspnet_regbrowsers.exe /i コマンドで定義を更新します。

どうしてもバイナリバージョンを更新したくない、かつ、該当環境で動くアプリケーション全てで IE10 の誤判定問題を解決したい、という場合にはこちらの方法になります。比較的運用管理者の方が好まれる方法かもしれません。

4. は、 開発者の方向けの対処です。前出のシステムのブラウザ定義ファイル(NET Framework インストールフォルダの CONFIG/Browsers サブフォルダにあるもの)は、更新した上に aspnet_regbrowsers.exe /i するという手間がかかります。しかし、あるアプリケーションでだけブラウザ定義を追加・変更したいのであれば、アプリケーションルート直下に App_Browsers というフォルダを作り、そこにブラウザ定義ファイルを用意する事が出来ます。

ただし、この時使用するブラウザ定義ファイルは、3. のものとは内容が異なります。

ブラウザ定義ファイルは、ツリー状に判定ルーチンが構成されており、アプリケーション毎のブラウザ判定では、システムの持っているルーチンにノードを追加するイメージでしか更新できません。つまり、システムのブラウザ判定が優先され、それで判定できなかった場合、またはそれで判定された結果をさらに細分化するような事しかできません。

従って、アプリ用の IE10 対応ブラウザ定義ファイルを入手する必要があります。これは NuGet で公開されています。

ASP.NET 4.0 用 (ASP.NET Browser Capabilities Update with IE10 and FF5 fixes for .NET 4)
https://www.nuget.org/packages/App_BrowsersUpdate

ASP.NET 2.0、3.0、3.5 用 (ASP.NET Browser Capabilities Update with IE10 fix for .NET 2.0)
https://www.nuget.org/packages/App_BrowsersUpdate.net20

NuGet をコマンドで叩いてもいいですが、もし Visual Studio 2010 以降をお使いであれば、Package Manager を使用してアプリケーションに追加する事が出来ます。下記は Visual Studio 2010 の Package Manager 導入手順ですが、Visual Studio 2012 では [NuGet パッケージの管理] メニューから "IE10" というキーワードで検索すると、上記がヒットすると思います。

.NETで開発モジュール導入が楽々に! NuGet入門
https://www.atmarkit.co.jp/fdotnet/chushin/nuget_01/nuget_01_01.html

これをアプリケーションに導入しておけば、ターゲット環境に緊急修正が入っているかどうか、セキュリティパッチが入っているかどうか、という事に関わらずアプリケーションで IE10 の誤判定問題に対応する事が出来ます。

 

以上、ご参考になれば幸いです。次回は日本ではややマイナー感のある、ASP.NET WebPages 2 について取り上げる予定です。

ではまた。
d99でした。