HttpClient and PushStreamContent

删除回忆录丶 提交于 2020-01-01 02:36:14

问题


I use PushStreamContent with my REST API (ASP.NET Web API) and works great. 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).

As HttpClient you have to do one little thing: Use 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?

I Implemented it as below, but the web api gets the request not before the client closes the stream.

         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:

public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)

This is necessary for the 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...

What do I have to do? Is the problem on the client side or maybe on the server / asp.net web api-side?

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):

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 ?


回答1:


I found the solution to my problem:

I want to set: httpWebRequest.AllowReadStreamBuffering = false;

HttpClient 4.0 does buffering by default and you cannot acces the property AllowReadStreamBuffering, so you have to use HttpWebRequest directly. (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)

The second problem was fiddler: Fiddler currently only supports streaming of responses and not requests (Fiddler makes HttpWebRequest/HttpClient behaviour unexpected)

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 ...



回答2:


Make sure to do 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...



来源:https://stackoverflow.com/questions/25429726/httpclient-and-pushstreamcontent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!