HttpWebRequest的分块/异步POST [英] HttpWebRequest chunked/async POST

查看:310
本文介绍了HttpWebRequest的分块/异步POST的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我想将一些动态生成的内容上传到我的网络API。
在客户端我使用HttpWebRequest。数据应该上传同步,我想写入流AFTER(!)我执行HTTP请求。



(从服务器到客户端它工作正常,但是从客户端到服务器我得到一些例外)。



客户端实现如下:



< HttpWebRequest httpWebRequest = HttpWebRequest.Create(myUrl)as HttpWebRequest;
httpWebRequest.Method =POST;
httpWebRequest.Headers [Authorization] =基本+ ...;
httpWebRequest.PreAuthenticate = true;

httpWebRequest.SendChunked = true;
//httpWebRequest.AllowWriteStreamBuffering = false; // does not help ...
httpWebRequest.ContentType =application / octet-stream;
Stream st = httpWebRequest.GetRequestStream();

任务< WebResponse> response = httpWebRequest.GetResponseAsync();

// NOW:在GetResponse()之后写入

var b = Encoding.UTF8.GetBytes(Test1);
st.Write(b,0,b.Length);

b = Encoding.UTF8.GetBytes(Test2);
st.Write(b,0,b.Length);

b = Encoding.UTF8.GetBytes(Test3);
st.Write(b,0,b.Length);

st.Close();

var x = response.Result;
Stream resultStream = x.GetResponseStream();
//做一些输出...

我得到异常(NotSupportedException:不支持并发IO读取或写入操作。)on stream.write()。



为什么我得到一个异常。有时候第一次写工作和后期写入抛出异常。
开始时,stream.CanWrite属性为true,但在第一次或第二次或第三次写入后,它会变为false ...然后在下一次写入时抛出异常。



编辑:更改AllowWriteStreamBuffering没有帮助



附录:
/ em>这个问题是由我的代码的顺序造成的。
我必须按以下顺序调用它:




  • GetRequestStream
    (向流写入异步)
    (请求在第一次写入后发送到服务器)
    然后:

  • GetResponseAsync()

  • GetResponseStream li>


我想GetResponseAsync触发客户端发送请求(现在只有头)。
但是没有必要,因为在将第一位写入流之后,请求已经发送。



我的问题的第二个原因:Fiddler。 (Fiddler目前只支持响应流而不是请求)

解决方案

我发现了我的问题。 b $ b这个问题是由我的代码的顺序造成的。我必须以这个顺序调用它:-GetRequestStream(向流写入异步)(请求在第一次写之后发送到服务器)然后:-GetResponseAsync()-GetResponseStream()



我想GetResponseAsync触发客户端发送请求(现在只有头)。但是没有必要,因为在将第一位写入流之后,请求已经发送。



我的问题的第二个原因:Fiddler。 (Fiddler目前仅支持响应流而不是请求)



编辑:带有HttpWebRequest的代码。

  HttpWebRequest httpWebRequest = HttpWebRequest.Create(http:// xxx)as HttpWebRequest; 
httpWebRequest.Method =POST;
httpWebRequest.Headers [Authorization] =基本+ Convert.ToBase64String(Encoding.ASCII.GetBytes(user:pw));
httpWebRequest.PreAuthenticate = true;

httpWebRequest.SendChunked = true;
httpWebRequest.AllowWriteStreamBuffering = false;
httpWebRequest.AllowReadStreamBuffering = false;
httpWebRequest.ContentType =application / octet-stream;
Stream st = httpWebRequest.GetRequestStream();
Console.WriteLine(Go);
try
{
st.Write(buffer,0,buffer.Length); //用第一次写,请求就会发送。
st.Write(buffer,0,buffer.Length);
st.Write(buffer,0,buffer.Length);

for(int i = 1; i <= 10; i ++)
{

st.Write(buffer,0,buffer.Length); //仍在写,而我可以在我的ASP.NET web上的流上读取api

}

st.Close();
}
catch(WebException ex)
{
var y = ex.Response;
}

//现在我们可以从服务器读取响应(分块)
任务< WebResponse> response = httpWebRequest.GetResponseAsync();

stream resultStream = response.Result.GetResponseStream();

byte [] data = new byte [1028];
int bytesRead;
while((bytesRead = resultStream.Read(data,0,data.Length))> 0)
{
string output = System.Text.Encoding.UTF8.GetString 0,bytesRead);
Console.WriteLine(output);
}

使用HttpClient类:

  HttpClientHandler ch = new HttpClientHandler(); 
HttpClient c = new HttpClient(ch);
c.DefaultRequestHeaders.TransferEncodingChunked = true;
c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(Basic,Convert.ToBase64String(Encoding.ASCII.GetBytes(user:pw)));

Stream stream = new MemoryStream();

var asyncStream = new AsyncStream(); //使用方法WriteToStream()的PushStreamContent的自定义实现
PushStreamContent streamContent = new PushStreamContent(asyncStream.WriteToStream);

HttpRequestMessage requestMessage = new HttpRequestMessage(new HttpMethod(POST),http:// XXX){Content = streamContent};
requestMessage.Headers.TransferEncodingChunked = true;

HttpResponseMessage response = await c.SendAsync(requestMessage,HttpCompletionOption.ResponseHeadersRead);

//自WriteToStream()方法中第一次写入以来发送请求。 p>

  response.EnsureSuccessStatusCode(); 

任务< Stream> result = response.Content.ReadAsStreamAsync();

byte [] data = new byte [1028]
int bytesRead;
while((bytesRead = await result.Result.ReadAsync(data,0,data.Length))> 0)
{
string output = System.Text.Encoding.UTF8.GetString (data,0,bytesRead);
Console.WriteLine(output);
}

Console.ReadKey();


Hi I want to upload some dynamic generated content to my web api. On the client I use the HttpWebRequest. The data should be uploaded sync and I want to write to the stream AFTER(!) I executed the HTTP-request.

(From server to client it does work fine, but from client to server i get some exceptions).

The client implementation looks like:

HttpWebRequest httpWebRequest = HttpWebRequest.Create(myUrl) as HttpWebRequest;
httpWebRequest.Method = "POST";
httpWebRequest.Headers["Authorization"] = "Basic " + ... ;
httpWebRequest.PreAuthenticate = true;

httpWebRequest.SendChunked = true;
//httpWebRequest.AllowWriteStreamBuffering = false; //does not help...
httpWebRequest.ContentType = "application/octet-stream";
Stream st = httpWebRequest.GetRequestStream();

Task<WebResponse> response = httpWebRequest.GetResponseAsync();

// NOW: Write after GetResponse()

var b = Encoding.UTF8.GetBytes("Test1");
st.Write(b, 0, b.Length);

b = Encoding.UTF8.GetBytes("Test2");
st.Write(b, 0, b.Length);

b = Encoding.UTF8.GetBytes("Test3");
st.Write(b, 0, b.Length);

st.Close();

var x = response.Result;
Stream resultStream = x.GetResponseStream();
//do some output...

I get exceptions (NotSupportedException: The stream does not support concurrent IO read or write operations.) on stream.write().

Why do I get here an exceptions. Some times the first writes worke and the late writes throw the exception. On the beginning the stream.CanWrite property is true, but after the first or second or thrird write it goes false... And then the exception is thrown on the next write.

Edit: Changing AllowWriteStreamBuffering did not help

Appendix: I found my problem. This problem is caused by the order of my code. I have to call it in this order:

  • GetRequestStream (writing async to the stream) (the request is send to the server after the first write) then:
  • GetResponseAsync()
  • GetResponseStream()

I thought "GetResponseAsync" triggers the client to send the Request (for now the headers only). But it is not necessary because the request is already send after I write the first bits to the stream.

Second cause of my problems: Fiddler. (Fiddler currently only supports streaming of responses and not requests)

解决方案

I found my problem. This problem is caused by the order of my code. I have to call it in this order: -GetRequestStream (writing async to the stream) (the request is send to the server after the first write) then: -GetResponseAsync() -GetResponseStream()

I thought "GetResponseAsync" triggers the client to send the Request (for now the headers only). But it is not necessary because the request is already send after I write the first bits to the stream.

Second cause of my problems: Fiddler. (Fiddler currently only supports streaming of responses and not requests)

Edit: The Code with "HttpWebRequest".

         HttpWebRequest httpWebRequest = HttpWebRequest.Create("http://xxx") as HttpWebRequest;
         httpWebRequest.Method = "POST";
         httpWebRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("user:pw"));
         httpWebRequest.PreAuthenticate = true;

         httpWebRequest.SendChunked = true;
         httpWebRequest.AllowWriteStreamBuffering = false;
         httpWebRequest.AllowReadStreamBuffering = false;
         httpWebRequest.ContentType = "application/octet-stream";
         Stream st = httpWebRequest.GetRequestStream();
         Console.WriteLine("Go");
         try
         {
               st.Write(buffer, 0, buffer.Length); //with the first write, the request will be send.
               st.Write(buffer, 0, buffer.Length);
               st.Write(buffer, 0, buffer.Length);

            for (int i = 1; i <= 10; i++)
            {

               st.Write(buffer, 0, buffer.Length); //still writing while I can read on the stream at my ASP.NET web api

            }

            st.Close();
         }
         catch (WebException ex)
         {
            var y = ex.Response;
         }

//now we can read the response from the server (chunked as well)
         Task<WebResponse> response = httpWebRequest.GetResponseAsync();

         Stream resultStream = response.Result.GetResponseStream();

         byte[] data = new byte[1028];
         int bytesRead;
         while ((bytesRead = resultStream.Read(data, 0, data.Length)) > 0)
         {
            string output = System.Text.Encoding.UTF8.GetString(data, 0, bytesRead);
            Console.WriteLine(output);
         }

With HttpClient class:

HttpClientHandler ch = new HttpClientHandler();
     HttpClient c = new HttpClient(ch);
     c.DefaultRequestHeaders.TransferEncodingChunked = true;
     c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes("user:pw")));

     Stream stream = new MemoryStream();

     var asyncStream = new AsyncStream(); //custom implementation for the PushStreamContent with the method "WriteToStream()"
     PushStreamContent streamContent = new PushStreamContent(asyncStream.WriteToStream);

     HttpRequestMessage requestMessage = new HttpRequestMessage(new HttpMethod("POST"), "http://XXX") { Content = streamContent };
     requestMessage.Headers.TransferEncodingChunked = true;

     HttpResponseMessage response = await c.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);

//the request is send since the first write in the "WriteToStream()" method.

     response.EnsureSuccessStatusCode();

     Task<Stream> result = response.Content.ReadAsStreamAsync();

     byte[] data = new byte[1028];
     int bytesRead;
     while ((bytesRead = await result.Result.ReadAsync(data, 0, data.Length)) > 0)
     {
        string output = System.Text.Encoding.UTF8.GetString(data, 0, bytesRead);
        Console.WriteLine(output);
     }

     Console.ReadKey();

这篇关于HttpWebRequest的分块/异步POST的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆