11

私は REST API (ASP.NET Web API) で PushStreamContent を使用しており、うまく機能しています。HttpClient はリソースを要求し、完全な要求がサーバーによって処理される前に HTTP 応答を取得できます (サーバーは引き続きプッシュ ストリームに書き込みます)。

HttpClient として、1 つの小さなことを行う必要があります。HttpCompletionOption.ResponseHeadersRead を使用します。

今私の質問:これを別の方法で行うことは可能ですか? HttpClient から -> プッシュ ストリームを介して Web 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)

これは Push-Stream に必要です。

これはどういうわけか可能ですか?最後のバイトがストリームに書き込まれるまで、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 コンテキスト?

4

2 に答える 2

5

私の問題の解決策を見つけました:

設定したい: httpWebRequest.AllowReadStreamBuffering = false;

HttpClient 4.0 はデフォルトでバッファリングを行い、プロパティ AllowReadStreamBuffering にアクセスできないため、HttpWebRequest を直接使用する必要があります。(または、HttpClinet 4.5 を使用できます。デフォルトの動作「ストリーミング」があります) http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-apiを参照してください。 / 6. HttpClient の使用)

2 番目の問題はフィドラーでした。フィドラーは現在、リクエストではなく応答のストリーミングのみをサポートしています (フィドラーは HttpWebRequest/HttpClient の動作を予期しないものにします) 。

私のために働いた解決策:

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 ...
于 2014-08-29T12:31:39.653 に答える