HttpWebRequestでちとハマってた ― 2007年09月04日 01時28分16秒
HttpWebRequestでCookieを使う
先週までのLL漬けからうって変わって、今日から久しぶりに.NETプログラミング。いや~、半年振りくらいのC#だもんで、結構コードかけなくなってるし。明日くらいまではちょっとリハビリ状態かしらん。
で、本題。これ知らずに今日は結構時間使ったのでメモ。でも.NET1.1だからいまやあまり役にたたん情報かも。
.NETアプリでWebアプリからちょっとしたデータを取得しようとしてたんだけど、まず手抜きでWebClient使って 認証リクエスト → データ取得処理 てな手順でコード書いてみたらうまくいかない。
Webアプリ側では認証とおってないリクエストはすべてログインフォームがあるページに飛ばすようにしてるんだけど認証リクエストの戻りからすでにログインフォームのコンテンツが返ってきてる状態。
おんなじ処理をJScriptでXHR使ってやってみたらこっちは認証とおって目的のデータがちゃんと取れてる。ふむ。
1.1のWebClientはかなり割り切った使い方をするものらしく(いままであんまり使ったことなかった)、URL直接食わせてコンテンツをダウンロードするくらいのインターフェイスしかないみたいなので、不精せずにHttpWebRequestに切り替えてみたんだけどこれも結果変わらず。
Webサーバのログを見てみると、一応希望のURLへのアクセスで200を返しているみたいだけどしつこくログインフォームのコンテンツだけが返ってくる。「ひょっとしてヘンなキャッシュ引いてるんじゃね?」とか思ったんだけどどうもそうでもない。
で、レスポンスヘッダ調べてるうちにPHPが返すセッションの値がリクエストごとに違っている。なんだ、そんな話かよ。
要するにサーバがCookieセットしようとしてるけどWebRequest側でそれを受け付けてないので、当然認証していないことになってたわけだ。
CookieContainer
と、ここまでわかったけどはて、どうやってCookieサポートするんだ?
でMSDNとにらめっこしてたらHttpWebRequestにCookieContainerやらいうプロパティがあることを発見。
解説の項を見てみると
CookieContainer プロパティは、要求に関連付けられている Cookie を格納する CookieContainer クラスのインスタンスを提供します。 CookieContainer の既定値は null 参照 (Visual Basic では Nothing) です。GetResponse メソッドが返す HttpWebResponse の Cookies プロパティで Cookie を返すには、CookieContainer オブジェクトをそのプロパティに割り当てる必要があります。などと、わかるようなわからんような記述がある。まぁHttpWebRequestでCookieの文言があるメンバも他に見当たらんし、これを使ってみるのかな。
で、このCookieContainerプロパティは型がまんま「System.Net.CookieContainer」クラスで、これがパラメータなしコンストラクタをサポートしてるので、こんな感じのコードを書いてみた(注:コード未検証。抜けとか間違いあるかも)。
CookieContainer cookie = new CookieContainer(); HttpWebRequest req = (HttpWebRequest)(WebRequest.Create( authUrl )); req.CookieContainer = cookie; using( HttpWebResponse res = (HttpWebResponse)(req.GetResponse()) ) { // 認証ページのコンテンツを取得 } // 同じCookieContainerを使いまわしてデータ取得URLへアクセス req = (HttpWebRequest)(WebRequest.Create( url ) ); req.CookieContainer = cookie; using( HttpWebResponse res = (HttpWebResponse)(req.GetResponse()) ) { // データを取得 }で試してみると、これで正解だったみたい。いやー、わからんかった。
つか、定番処理っぽい
ちと時間くったけど、まぁ最悪「MSXMLをtlbimpするかぁ?」とか考えてたワケで、それに比べればマシなのでほっとしてたんだけど、あとでなんとなくぐぐってみたらいっぱい引っかかるじゃん。探し方悪すぎ。orz
最近のコメント