HttpWebRequestを使ってPOSTメソッドでリクエストする

認証処理等でPOSTメソッドを投げる必要があります。HttpWebRequestを使って.NET FrameworkでPOSTメソッドのリクエストを行う場合、リクエストストリームにデータを書き込んで、更にレスポンスストリームを取得する必要があります。Reactive Extensionsを使って実装してみました。

  public void PostRequest(string url, Dictionary<string, string> dic) {
 
      // クエリ文字列の生成
      var postData = string.Join("&",
          dic.Select(p => string.Format("{0}={1}", p.Key, p.Value)).ToArray()
      );
 
      var req = HttpWebRequest.CreateHttp(url);
      req.AllowAutoRedirect = false;
      req.Method = "POST";
      req.ContentType = "application/x-www-form-urlencoded";
 
      var writeStreamObservable = 
          Observable.FromAsyncPattern<Stream>(req.BeginGetRequestStream, req.EndGetRequestStream);
      var responseObservable = 
          Observable.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse);
 
      writeStreamObservable()
          .SelectMany(reqStrm => {
              var buf = Encoding.UTF8.GetBytes(postData);
              reqStrm.Write(buf, 0, buf.Length);
              reqStrm.Close();
              return responseObservable();
          })
          .Select(res => {
              using (var s = new StreamReader(res.GetResponseStream()))
                  return s.ReadToEnd();
          })
          .ObserveOnDispatcher()
          .Subscribe(text => textBlock1.Text = text);
  }

使い方としてこんな感じ。ボタンをタップした時に、POSTリクエストを行うのを想定しています。

  private void button2_Click(object sender, RoutedEventArgs e) {
      var dic = new Dictionary<string, string>() {
              { "api_key", "アプリキー" },
              { "email", "hoge@example.com" }, 
              { "password", "パスワード" }
      };
      PostRequest("http://api.tinami.com/auth", dic);
  }