2011-08-14 7 views
2

msdnでHTTP POSTの例を見つけましたが、こちらでどのように反応拡張を利用できるのでしょうか?Windows上で反応的な拡張機能を使用してHTTP POSTを行う方法

using System; 
using System.Net; 
using System.IO; 
using System.Text; using System.Threading; 

class HttpWebRequestBeginGetRequest 
{ 
    private static ManualResetEvent allDone = new ManualResetEvent(false); 

    public static void Main(string[] args) 
    { 


     // Create a new HttpWebRequest object. 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/example.aspx"); 

     request.ContentType = "application/x-www-form-urlencoded"; 

     // Set the Method property to 'POST' to post data to the URI. 
     request.Method = "POST"; 

     // start the asynchronous operation 
     request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request); 

     // Keep the main thread from continuing while the asynchronous 
     // operation completes. A real world application 
     // could do something useful such as updating its user interface. 
     allDone.WaitOne(); 
    } 

    private static void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 

     // End the operation 
     Stream postStream = request.EndGetRequestStream(asynchronousResult); 

     Console.WriteLine("Please enter the input data to be posted:"); 
     string postData = Console.ReadLine(); 

     // Convert the string into a byte array. 
     byte[] byteArray = Encoding.UTF8.GetBytes(postData); 

     // Write to the request stream. 
     postStream.Write(byteArray, 0, postData.Length); 
     postStream.Close(); 

     // Start the asynchronous operation to get the response 
     request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); 
    } 

    private static void GetResponseCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 

     // End the operation 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); 
     Stream streamResponse = response.GetResponseStream(); 
     StreamReader streamRead = new StreamReader(streamResponse); 
     string responseString = streamRead.ReadToEnd(); 
     Console.WriteLine(responseString); 
     // Close the stream object 
     streamResponse.Close(); 
     streamRead.Close(); 

     // Release the HttpWebResponse 
     response.Close(); 
     allDone.Set(); 
    } 
} 

次のコードを使用しようとしていますが、機能しません。誰かがこれで私を助けることができますか?

return (from request in 
       Observable.Return((HttpWebRequest)WebRequest.Create(new Uri(postUrl))).Catch(Observable.Empty<HttpWebRequest>()) 
       .Do(req => 
         { 
          // Set up the request properties 
          req.Method = "POST"; 
          req.ContentType = contentType; 
          req.UserAgent = userAgent; 
          req.CookieContainer = new CookieContainer(); 
          Observable.FromAsyncPattern<Stream>(req.BeginGetRequestStream, req.EndGetRequestStream)() 
           .ObserveOnDispatcher() 
           .Subscribe(stream => 
             { 
              stream.Write(formData, 0, 
                 formData.Length); 
              stream.Close(); 

             }) 
           ; 

         }) 
      from response in 
       Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)().Catch(Observable.Empty<WebResponse>()) 
      from item in GetPostResponse(response.GetResponseStream()).ToObservable().Catch(Observable.Empty<string>()) 
      select item).ObserveOnDispatcher(); 

編集-Peng事前に ありがとう:それを明確にするには、私は、MSDNの例では、同じロジックを実装するために、RXを使用したいです。 MSDNの例では、まずRequestStreamを書き込むための非同期呼び出しを行い、次にGetRequestStreamCallbackでは、別の非同期呼び出しを呼び出して応答を取得するようです。 のRxを使用して、私は 1 Observable.FromAsyncPattern(request.BeginGetRequestStream、request.EndGetRequestStream)() 2. Observable.FromAsyncPattern(request.BeginGetResponse、request.EndGetResponseを)()2つの観測を作成することができています 問題があります観測可能なものは最初のものの結果に依存するので、どうすればRxでこれを行うことができますか? 最初の観測対象のサブクライブメソッドで、観測可能な観測対象を作成しますか?それは良い方法ですか?

+0

あなたのコードは少し複雑です。どのように動作しませんか?例外?何も起こりません – ColinE

答えて

1

これが私のやり方です。 2つのAsyncパターンを前面に設定してから、SelectManyを使用してそれらを連鎖させます。
私はこのコードからエラー処理などを切り離して、シンプルに保ち、最小限しか働かせないようにしました。独自のコードに似た.Catch()を追加する必要があります。文字列以外のもの(レスポンスコードなど)を取得するには、データのすべてのビットを保持するクラス/構造体を作成する必要がありますあなたはそれを必要とし、代わりにそれを返す。

public IObservable<string> BeginPost(Uri uri, string postData) { 
    var request = HttpWebRequest.CreateHttp(uri); 
    request.Method = "POST"; 
    request.ContentType = "application/x-www-form-urlencoded"; 

    var fetchRequestStream = Observable.FromAsyncPattern<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream); 
    var fetchResponse = Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse); 
    return fetchRequestStream().SelectMany(stream => { 
    using (var writer = new StreamWriter(stream)) writer.Write(postData); 
    return fetchResponse(); 
    }).Select(result => { 
    var response = (HttpWebResponse)result; 
    string s = ""; 
    if (response.StatusCode == HttpStatusCode.OK) { 
     using (var reader = new StreamReader(response.GetResponseStream())) s = reader.ReadToEnd(); 
    } 
    return s; 
    }); 
} 
+0

私は欲しいものを見て、それを試してみます –

1

あなたの問題は、DOの使用は、()ここでは、あなたがあなたのSelectManyにGetRequestStreamを移動する必要がある(にあなたの...「BLAからBLAからで、中に」)それだけに理にかなっているので、の後にレスポンスストリームを取得してください。今、あなたは両方を同時にしようとしています。

+0

はい、それは私のmisunstandingです、指摘のおかげで –

関連する問題