如何在windows phone 7上使用响应式扩展制作HTTP POST



我在msdn中找到了一个关于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();
     }
 }

我试图使用下面的代码,但它不工作。有人能帮我一下吗?提前感谢-Peng

    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();
编辑:为了说清楚,我想使用rx在MSDN示例中实现相同的逻辑。在MSDN示例中,它似乎首先进行异步调用以写入RequestStream,然后在GetRequestStreamCallback中,触发另一个异步调用以获得响应。使用Rx,我可以创建2个可观察对象1. Observable.FromAsyncPattern(请求。BeginGetRequestStream request.EndGetRequestStream) ()2. Observable.FromAsyncPattern(请求。BeginGetResponse request.EndGetResponse) ()问题是,第二个可观测值依赖于第一个的结果,我怎么在Rx中做到这一点?在第一个可观察对象的subscribe方法中创建第二个可观察对象?这是好方法吗?

我是这样做的。我预先配置了两个异步模式,然后使用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;
  });
}

您的问题是您在这里使用Do(),您需要将GetRequestStream移动到您的SelectMany(到您的"from bla in, from bla in"…)中,因为只有在之后才有意义获得响应流您已经编写了完整的请求。现在,你正试图同时做这两件事。

相关内容

  • 没有找到相关文章

最新更新