繁体   English   中英

HTTPClient.PostAsync 仅在发布较大文件时抛出异常

[英]HTTPClient.PostAsync throws exception only when posting larger file

我有以下代码用于使用 POST 将文件上传到 REST 服务。

它适用于较小的文件,但它对较大的文件抛出异常,较大的我的意思是大约 800 KB。

public async Task<bool> UploadInputFileAsync(FileDTO file)
{
    using (HttpClientHandler httpClientHandler = new HttpClientHandler())
    {
        httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
        httpClientHandler.ClientCertificates.Add(clientCertificate);
        string url = $"{Configuration.FileService.Url}";

        using (HttpClient httpClient = new HttpClient(httpClientHandler))
        {
            httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
            MultipartFormDataContent multiForm = new MultipartFormDataContent();

            using (FileStream fs = System.IO.File.OpenRead(Path.Combine(Configuration.FileService.InputFilesPath, file.FileName)))
            {
                multiForm.Add(new StreamContent(fs), "file", file.FileName);

                using (HttpResponseMessage response = await httpClient.PostAsync(url, multiForm))
                {
                    response.EnsureSuccessStatusCode();
                    return true;
                }
            }
        }
    }
}

抛出的异常如下

System.Net.Http.HttpRequestException: Error while copying content to a stream.
 ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
 ---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.Security.SslStream.<WriteSingleChunk>g__CompleteAsync|210_1[TWriteAdapter](ValueTask writeTask, Byte[] bufferToReturn)
   at System.Net.Security.SslStream.WriteAsyncChunked[TWriteAdapter](TWriteAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.WriteAsyncInternal[TWriteAdapter](TWriteAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Http.HttpConnection.WriteAsync(ReadOnlyMemory`1 source)
   at System.Net.Http.HttpConnection.ChunkedEncodingWriteStream.<WriteAsync>g__WriteChunkAsync|2_0(HttpConnection connection, ReadOnlyMemory`1 buffer)
   at System.IO.Stream.CopyToAsyncInternal(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at System.Net.Http.HttpContent.CopyToAsyncCore(ValueTask copyTask)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpContent.CopyToAsyncCore(ValueTask copyTask)
   at System.Net.Http.MultipartContent.SerializeToStreamAsyncCore(Stream stream, TransportContext context, CancellationToken cancellationToken)
   at System.Net.Http.HttpContent.CopyToAsyncCore(ValueTask copyTask)
   at System.Net.Http.HttpConnection.SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)

使用 Wireshark 我得到以下流量,并且在 FIN,ACK 之后连接似乎没有正常关闭

Wireshark 跟踪

任何帮助,将不胜感激。

稍后编辑

谢谢你的帮助。

似乎我的问题是由 SocketsHttpHandler 实现中的一个错误产生的,该错误仍然存​​在于 .NET Core 3.1 中(尽管他们建议它已在 3.1 中修复),我发现这里描述了https://github.com/dotnet/runtime/issues/ 27415

解决方案是添加

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

在方法的开头。

An existing connection was forceed close by the remote host ”这句话告诉我们问题出在请求的接收端。 如果我们有一个格式错误的请求,它会为所有文件给出错误,但是,我们的情况不同。 也许,接收端已强制执行file size limitrequest timeout ,这不允许请求成功完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM