ASP.NETでリクエストとレスポンスを使用する
※この章を読むにはリクエストとレスポンスの仕組みの理解が必要です。
WEBサーバーへのGETリクエスト
例えば以下のリクエストがサーバーに届いた場合について考えて見ます。
GET http://article.higlabo.com/ja/index.html HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: ja-JP
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: article.higlabo.com
ASP.NETではこれらの値をRequestオブジェクトから簡単に取得できるようになっています。(クリックで拡大)
リクエストのHTTPメソッドの種類は以下のように取得できます。
var methodName = Request.HttpMethod;
リクエストしたURLは以下のように書けばUriオブジェクトを取得できます。
var u = Request.Url;
ヘッダの各値は以下のように取得できます。
var accept = Request.Headers["Accept"];
var language = Request.Headers["Accept-Language"];
var userAgent = Request.Headers["User-Agent"];
//...そのほかの値
var host = Request.Headers["Host"];
本来であれば送られてきた文字列を自分で解析して値を取得する必要がありますがASP.NETでは上記のように簡単に値が取れるようになっています。
クエリ文字列の取得
URLの最後に?をつけて[キー1=値1&キー2=値2&…]というフォーマットでサーバーに値を送信することができます。 この?の後ろの部分をクエリ文字列といいます。
GET http://article.higlabo.com/ja/index.html?category=csharp&start=0&end=10 HTTP/1.1
クエリ文字列のそれぞれの値をサーバーで取得するには以下のように書きます。
var category = Request.QueryString["category"];
var start = Request.QueryString["start"];
var end = Request.QueryString["end"];
ヘッダーと同じ書き方なので容易に利用が可能です。
同じキーで値が複数設定されている場合、GetValuesメソッドが利用できます。 例えばクエリ文字列が?category=sports&category=music&category=tvの場合
String categoryText = Request.QueryString["category"]; //sports,music,tv
String[] categoryList = Request.QueryString.GetValues("category");
という形でクエリ文字列のそれぞれの値を取得可能です。
クッキーの値の取得
ブラウザからどのようなクッキーが送られているかはRequestオブジェクトのHeadersプロパティから取得可能です。
String cookie = Request.Headers["Cookie"];
しかしこのプロパティからはクッキーとして設定された全ての値が[キー1=値1&キー2=値2&...]という形で文字列で取得されます。 この文字列を自分で解析して値を取得するのは大変です。そこでRequestオブジェクトには別途Cookiesプロパティがありそれぞれのキーの値が簡単に取得できます。
HttpCookie hc = Request.Cookies["UserID"];
String userID = hc.Value;
クッキーの発行をするにはResponseオブジェクトにクッキーを追加します。Requestオブジェクトではないので注意してください。
var hc = new HttpCookie("UserID", "123");
Response.Cookies.Add(hc);
Fiddlerでレスポンスのヘッダを見ると以下のような値を確認できます。
Set-Cookie: UserID=123; path=/
ブラウザはサーバーからSet-Cookieというキーで値が送られてきた場合には次回そのドメインへリクエストを送るときにヘッダにCookieというキーにこの値をセットして送るようになっています。
クッキーには複数の値が設定されている場合もあります。以下のようにすると複数の値をセット可能です。
var hc = new HttpCookie("UserInfo");
hc.Values.Add("userID", "123");
hc.Values.Add("userName", "higty");
Response.Cookies.Add(hc);
Fiddlerでレスポンスを見ると以下のようになっています。
Set-Cookie: UserInfo=userID=123&userName=higty; path=/
このように複数の値がセットされたクッキーの場合は以下のようにして値を取得します。
String userID = Request.Headers["UserInfo"].Values["userID"]; 
String userName = Request.Headers["UserInfo"].Values["userName"]; 
POSTリクエストの場合
次にPOSTの場合についてFiddlerを使用して動作を見てみます。GETの場合はヘッダ情報だけ送られてきましたがPOSTの場合はヘッダ+ボディの情報がクライアントからサーバーへ送信されます。 形式は以下のようになります。
POST http://article.higlabo.com/ja/send_mail.aspx HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: ja-JP
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: article.higlabo.com

mailaddress=xxx%40gmail.com&title=Test&detail=%E3%83%86%E3%82%B9%E3%83%88%E3%83%A1
%E3%83%BC%E3%83%AB
ボディにはいくつかのフォーマットがあります。
application/x-www.form-urlencoded
multipart/form-data
送信されてきたボディの値をサーバー側で取得するには以下のように書きます。
var mailAddress = Request.Form["mailaddress"];
var title = Request.Form["title"];
var detail = Request.Form["detail"];

次に添付ファイルつきのリクエストについて解説します。例えば以下のようなリクエストが送信された場合
POST http://article.higlabo.com/Upload.aspx HTTP/1.1
Content-Type: multipart/form-data; boundary=7dc3151a404be
Content-Length: 420

--7dc3151a404be
Content-Disposition: form-data; name="image_file"; filename="Print24.png"
Content-Type: image/png

[画像のバイトデータ]
--7dc3151a404be
Content-Disposition: form-data; name="image_title"

MyPicture.png
--7dc3151a404be--
送信された添付ファイルのデータを取得するには以下のように書きます。
HttpPostedFile f = Request.Files["image_file"];
var length = f.ContentLength;
Byte[] bb = new Byte[length];
f.InputStream.Read(bb, 0, bb.Length);
使用しないほうがよい後方互換性のための機能
Request["myKey"]という書き方でForm,QueryString,Cookies,ServerVariableの値を取得することが可能です。 内部コードは以下のようになっています。
public string get_Item(string key)
{
    string text1 = this.QueryString[key];
    if (text1 != null)
    {
        return text1;
    }
    text1 = this.Form[key];
    if (text1 != null)
    {
        return text1;
    }
    HttpCookie cookie1 = this.Cookies[key];
    if (cookie1 != null)
    {
        return cookie1.Value;
    }
    text1 = this.ServerVariables[key];
    if (text1 != null)
    {
        return text1;
    }
    return null;
}
Request.Params["myKey"]でも同様に取得することが可能です。内部コードは以下のようになっています。
public NameValueCollection Params
{
    get
    {
        InternalSecurityPermissions.AspNetHostingPermissionLevelLow.Demand();
        if (this._params == null)
        {
            this._params = new HttpValueCollection();
            this.FillInParamsCollection();
            this._params.MakeReadOnly();
        }
        return this._params;
    }
}            
private void FillInParamsCollection()
{
    this._params.Add(this.QueryString);
    this._params.Add(this.Form);
    this._params.Add(this.Cookies);
    this._params.Add(this.ServerVariables);  
}   
ただこの書き方は使用しないほうが懸命です。より取得元が限定的な書き方をしたほうがプログラムの堅牢性があがります。 例えばFormの値を利用する以下のコードを書いている場合にポストされてくる値が024だったとします。
String userID = Request.Params["user_id"];
この場合userIDには024という値が入ります。 しかしたまたまクエリ文字列がhttp://www.mypage.com/index.html?user_id=0123 といった形で重複してしまうとRequest.Params["user_id"]で取得される値は024,0123というカンマ区切りの値になります。 注意しましょう。
Create at 2012/9/24 LastUpdate 2012/12/10