我将PushStreamContent与我的REST API(ASP.NET Web API)一起使用,效果很好。 HttpClient可以请求一个ressource并在服务器处理完整请求之前获取HTTP响应(服务器仍然写入推送流)。
作为HttpClient,你必须做一件小事:使用HttpCompletionOption.ResponseHeadersRead。
现在我的问题: 是否有可能以另一种方式? 来自HttpClient - >通过推送流将数据上传到网络API?
我实现了如下所示,但是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();
AsyncStream是我的代表:
public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
这对推送流是必要的。
这有可能吗? HttpClient不会将请求发送到Web api,直到最后一个字节写入流...
我该怎么办?问题出在客户端还是在服务器/ asp.net web api端?
编辑: 这是WriteToStream的实现(但我不使用磁盘中的文件,使用内存流'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();
}
}
也许我必须做一些事情:HttpContent内容,TransportContext上下文?
答案 0 :(得分:5)
我找到了解决问题的方法:
我想设置:httpWebRequest.AllowReadStreamBuffering = false;
HttpClient 4.0默认执行缓冲,您无法访问属性AllowReadStreamBuffering,因此您必须直接使用HttpWebRequest。 (或者您可以使用HttpClinet 4.5,默认行为'streaming')请参阅:http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/ 6.使用HttpClient)
第二个问题是fiddler:Fiddler目前只支持响应流而不是请求(Fiddler makes HttpWebRequest/HttpClient behaviour unexpected)
对我有用的解决方案:
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 ...
答案 1 :(得分:2)
确保在您的请求消息上执行requestMessage.Headers.TransferEncodingChunked = true;
...原因是如果您不设置此消息,HttpClient将缓冲客户端本身的整个内容,以便找出内容长度请求,这就是您注意到在写入流时没有立即调用您的web api服务的原因...