[英]HttpClient and PushStreamContent
I use PushStreamContent with my REST API (ASP.NET Web API) and works great. 我将RESTAPI(ASP.NET Web API)与PushStreamContent一起使用,效果很好。 The HttpClient can request a ressource and gets the HTTP-Response before the complete request is handled by the server (the server still writes to the push-stream). HttpClient可以请求资源,并在服务器处理完整的请求之前获取HTTP-Response(服务器仍然写入推流)。
As HttpClient you have to do one little thing: Use HttpCompletionOption.ResponseHeadersRead. 作为HttpClient,您必须做一件事:使用HttpCompletionOption.ResponseHeadersRead。
Now my question: Is it possible to to this the other way? 现在我的问题是:是否有可能这样做呢? From the HttpClient -> uploading data via a push-stream to the web api? 从HttpClient->通过推送流将数据上传到Web API?
I Implemented it as below, but the web api gets the request not before the client closes the stream. 我实现了如下,但Web api不会在客户端关闭流之前获取请求。
var asyncStream = new AsyncStream(fs);
PushStreamContent streamContent = new PushStreamContent(asyncStream.WriteToStream);
content.Add(streamContent);
HttpResponseMessage response = await c.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), "http://localhost/...") { Content = content }, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
The AsyncStream is my class with the delegate: AsyncStream是我的代表类:
public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
This is necessary for the Push-Stream. 这对于Push-Stream是必需的。
Is this possible somehow? 这有可能吗? The HttpClient do not send the request to the web api until the last bytes are written to the stream... 在将最后一个字节写入流之前,HttpClient不会将请求发送到Web api。
What do I have to do? 我需要做什么? Is the problem on the client side or maybe on the server / asp.net web api-side? 问题出在客户端还是服务器/ asp.net Web api端?
Edit: This is the implemenation of WriteToStream (but I do not use a file from disk, is use a memorystream 'myMemoryStream' (passed in the constructor): 编辑:这是WriteToStream的实现(但我不使用磁盘中的文件,而是使用memorystream'myMemoryStream'(在构造函数中传递):
public void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
{
try
{
var buffer = new byte[4096];
using (var stream = myMemoryStream)
{
var bytesRead = 1;
while (bytesRead > 0)
{
bytesRead = video.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
}
}
}
catch (HttpException ex)
{
return;
}
finally
{
outputStream.Close();
}
}
Maybe I have to do something with: HttpContent content, TransportContext context ? 也许我必须做些事情:HttpContent内容,TransportContext上下文?
I found the solution to my problem: 我找到了解决问题的方法:
I want to set: httpWebRequest.AllowReadStreamBuffering = false; 我要设置:httpWebRequest.AllowReadStreamBuffering = false;
HttpClient 4.0 does buffering by default and you cannot acces the property AllowReadStreamBuffering, so you have to use HttpWebRequest directly. HttpClient 4.0默认情况下会进行缓冲,并且您无法访问属性AllowReadStreamBuffering,因此必须直接使用HttpWebRequest。 (Or you can use HttpClinet 4.5, there is the default behaviour 'streaming') see: http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/ 6. Using HttpClient) (或者您可以使用HttpClinet 4.5,这是默认行为“流式传输”),请参见: http : //www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api / 6.使用HttpClient)
The second problem was fiddler: Fiddler currently only supports streaming of responses and not requests ( Fiddler makes HttpWebRequest/HttpClient behaviour unexpected ) 第二个问题是提琴手:提琴手当前仅支持响应流而不是请求( 提琴手使HttpWebRequest / HttpClient行为出乎意料 )
The solution that worked for me: 对我有用的解决方案:
HttpWebRequest httpWebRequest = HttpWebRequest.Create(...)
httpWebRequest.Method = "POST";
httpWebRequest.Headers["Authorization"] = "Basic " + ...;
httpWebRequest.PreAuthenticate = true;
httpWebRequest.AllowWriteStreamBuffering = false;
httpWebRequest.AllowReadStreamBuffering = false;
httpWebRequest.ContentType = "application/octet-stream";
Stream st = httpWebRequest.GetRequestStream();
st.Write(b, 0, b.Length);
st.Write(b, 0, b.Length);
//...
Task<WebResponse> response = httpWebRequest.GetResponseAsync();
var x = response.Result;
Stream resultStream = x.GetResponseStream();
//... read result-stream ...
Make sure to do requestMessage.Headers.TransferEncodingChunked = true;
确保执行requestMessage.Headers.TransferEncodingChunked = true;
on your request message...the reason is if you do not set this, HttpClient would buffer the entire content at the client itself in order to figure out the Content-length of the request and this is the reason you are noticing your web api service not being invoked immediately as you are writing to the stream... 在您的请求消息上...原因是如果您未设置此项,则HttpClient会在客户端本身缓冲整个内容,以便找出请求的Content-length,这就是您注意到Web api的原因正在写入流时,服务不会立即被调用...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.