SilverlightにHttpWebRequestがある件

「System.Net」アセンブリに「HttpWebRequest」クラスがある・・・orz

アセンブリ分かれてやんの。

しかも同期呼び出しをサポートしている・・・ゴクリしていなかった・・・orz。

オブジェクトブラウザで見ると「GetResponse」メソッドがあるのに、Intellisenceには表示されないし、コンパイルもできない。Silverlightこんなの多いよねぇ。

実際にPOSTしようとするとこんな感じか。

var data = new Dictionary<string, object>() {
    { "firstName", "ほげ" },
    { "lastName", "太郎" }
};
var postData = string.Join("&",
    data.Select(p => string.Format("{0}={1}", p.Key, p.Value)).ToArray()
);

var webReq = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://localhost/hoge.aspx"));
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.BeginGetRequestStream(r1 => {
    using(var stm = webReq.EndGetRequestStream(r1)) {
        var buf = Encoding.UTF8.GetBytes(postData.ToString());

        stm.Write(buf, 0, buf.Length);
    }
    webReq.BeginGetResponse(r2 => {
        var webRes = (HttpWebResponse)webReq.EndGetResponse(r2);

        using(var sr = new StreamReader(webRes.GetResponseStream())) {
            sr.ReadToEnd();
        }

    }, null);

}, null);

非同期ばっかりなんで、だいぶだるい。


でも、こういう拡張メソッドを作っておけば楽になる。

HttpWebRequestExtension.cs

/// <summary>
/// HttpWebRequestに機能を追加する拡張クラス
/// </summary>
static class HttpWebRequestExtension {
    /// <summary>
    /// 指定したWebリクエストを使って、指定したデータをPOSTします。
    /// </summary>
    /// <param name="webReq">Webリクエスト</param>
    /// <param name="data">データ</param>
    /// <param name="callback">POSTが完了した時のコールバック</param>
    public static void Post(this HttpWebRequest webReq, IDictionary<string, object> data, Action<HttpWebResponse> callback) {
        var postData = string.Join("&",
            data.Select(p => string.Format("{0}={1}", p.Key, p.Value)).ToArray()
        );
        webReq.Method = "POST";
        webReq.ContentType = "application/x-www-form-urlencoded";
        webReq.BeginGetRequestStream(r1 => {
            using(var stm = webReq.EndGetRequestStream(r1)) {
                var buf = Encoding.UTF8.GetBytes(postData);

                stm.Write(buf, 0, buf.Length);
            }
            webReq.BeginGetResponse(r2 => {
                var webRes = (HttpWebResponse)webReq.EndGetResponse(r2);

                if(callback != null) callback(webRes);

            }, null);

        }, null);
    }
}

使用例

var webReq = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://localhost/hoge.aspx"));
webReq.Post(new Dictionary<string, object>() {
    { "firstName", "ほげ" },
    { "lastName", "太郎" }
}, webRes => {
    // Do something
});

拡張メソッド万歳!!