コンテンツへスキップ

ASP.NET 文字セットの異なるページからPOSTを受付けるには

2008年6月12日
けろ-みおさんの、MSDNライブラリへの指摘で思い出した。
 
これには昔嵌められた。
ページディレクティブにRequestEncodingを書けるような表現がMSDNライブラリに記載されているのに、実際そのようにやってみるとエラーになる。
書いてあるのにできないので諦めるに諦めきれず、諦めるまでに随分時間を費やした記憶がある。
 
では、本題に。
 
とあるASP.NET Webアプリケーション(Aアプリ)がある。
Aアプリのアプリケーションレベルのweb.configのグローバリゼーションはこんなかんじ。
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
 
別のWebアプリケーション(Bアプリ)がある。
Bアプリのアプリケーションレベルのweb.configのグローバリゼーションはこんなかんじ。
<globalization requestEncoding="shift-jis" responseEncoding="shift-jis" />
 
BアプリのあるページからAアプリのあるページ(/external/kame.aspxとする)に、データ連携のためにPOSTする。
Aアプリでは、POSTされたデータをページに表示・ユーザーによる編集の後に、登録ボタンでAアプリのDBに登録する仕様とする。
 
さて、このままだと、Aアプリの/external/kame.aspxで受け取った、BアプリからのPOSTデータは文字化けする。
Aアプリの設定ではrequestEncoding="utf-8"のため、Bアプリからのshift-jisをutf-8で解釈しようとするから。
 
影響・手間を最小限にするには、Aアプリのアプリケーションレベルのweb.configでlocation要素を使用して、グローバリゼーションを変更したいページをピンポイントで指定する。
<configuration>
  <location path="external/kame.aspx">
    <system.web>
      <globalization requestEncoding="shift-jis" responseEncoding="shift-jis" />
    </system.web>
  </location>
</configuration>
必ずしもアプリケーションレベルのweb.configでなくてもよく、externalフォルダにweb.configを新たに作成して上記のように記述してもよい。
その場合のlocation要素は path="kame.aspx" になる。
なお、requestEncodingとresponseEncodingの設定値が同一でない場合、ポストバックで文字化けすることになる。
もし、requestEncoding="shift-jis" responseEncoding="utf-8" だったら、まず最初のGETリクエストでutf-8のページがブラウザに表示され、ユーザーが編集してポストバックすると、shift-jisでのリクエストを期待しているので化ける。
 
web.configでの設定の他に、global.asaxでコードを書くやり方もある。
けろ-みおさんに教えてもらった。
Application_BeginRequestで GlobalizationSection.RequestEncoding プロパティ を調整する。※コレ私の勘違いのため間違いです!ごめんなさい。
Application_BeginRequestで HttpRequest.ContentEncoding プロパティ を調整する。※教えてもらったのはこっち!
リファラ情報などを元に、きめ細かい制御ができそう。 
 
最後に、globalization 要素 (ASP.NET 設定スキーマ)を今回初めて熟読して気がついたことがある。
requestEncodingの説明に、次の記述がある。
要求の要求ヘッダーに Accept-Charset 属性が含まれる場合は、この属性が構成内のこの属性をオーバーライドします。
おそらく、form要素のaccept-charset属性に設定してある値が、リクエストのHTTPヘッダに乗っかってくるんだと思う。
てことは、Aアプリで対応する必要はなく、Bアプリ作ってる人に「form要素のaccept-charset属性にutf-8を設定してね」と頼めばいいだけだったのか?!
 
 

From → .NET

4件のコメント
  1. けろ-みお permalink

    >Configuration関係のプロパティの設定値をコードから変更しちゃうのは良くないですよね。orz
     
    あ、でもそうですね。おっしゃる通り、Configurationの設定をその時だけ動的に変えるので
    あまり良いとは言えないかもしれませんね。
    となると、HttpRequest.ContentEncodingの方が、現実的かなと思いましたw
    これは私も良くApplication_BeginRequestで使用しますw

コメントを残す