.NET 6.0 使用 HttpClient 发布 MultipartFormDataContent 结果 'Error while copying content to a stream'
.NET 6.0 Posting MultipartFormDataContent with HttpClient result in 'Error while copying content to a stream'
我正在尝试 POST 使用 HttpClient (.NET 6.0) 和 MultipartFormDataContent
的特定文件,但我不断收到以下错误:Error while copying content to a stream
但是,当通过Postman或通过服务器自己的门户网站上传文件时,它是成功的。不幸的是,我无法访问远程服务器,无法知道它失败的原因。
下面是删除了一些信息的示例代码。
public static class Program {
private static HttpClient client;
private static HttpClientHandler httpClientHandler;
private static async Task Main() {
httpClientHandler = new HttpClientHandler() {
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
client = new HttpClient(httpClientHandler);
client.BaseAddress = new Uri("https://remoteServerIpAddress/");
var filePath = "absoluteFilePath";
var fileBytesArray = File.ReadAllBytes(filePath);
var multipartFormContent = new MultipartFormDataContent();
multipartFormContent.Add(new ByteArrayContent(fileBytesArray));
// Setup headers for authorization
// Error occurs here
var uploadResponse = await client.PostAsync("api/upload", multipartFormContent).ConfigureAwait(true);
Console.WriteLine(await uploadResponse.Content.ReadAsStringAsync());
}
}
下面是错误的堆栈跟踪:
System.Net.Http.HttpRequestException
HResult=0x80131620
Message=Error while copying content to a stream.
Source=System.Net.Http
StackTrace:
at System.Net.Http.HttpContent.<<CopyToAsync>g__WaitAsync|56_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.MultipartContent.<SerializeToStreamAsyncCore>d__23.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.HttpContent.<<CopyToAsync>g__WaitAsync|56_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpConnection.<SendRequestContentAsync>d__68.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.HttpConnection.<SendAsyncCore>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Net.Http.HttpConnection.<SendAsyncCore>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpConnectionPool.<SendWithVersionDetectionAndRetryAsync>d__83.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Program.<Main>d__2.MoveNext() in C:\Projects\UploadApplication\Program.cs:line 59
Inner Exception 1:
IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host..
Inner Exception 2:
SocketException: An existing connection was forcibly closed by the remote host.
我见过类似的 post,但没有看到任何对我的情况有帮助的解决方案:
我不确定问题是否出在我的代码中,但如果有任何想法或想法,我们将不胜感激。
我们在之前的项目中遇到过这个问题。对我们有用的是使用需要 name
和 fileName
参数的 add 方法的重载之一。
multipartFormContent.Add(new ByteArrayContent(fileBytesArray), "name", "fileName")
我已经确定了问题,事实证明 MultipartFormDataContent
默认在边界值周围添加双引号,而服务器 Web 门户和 Postman 没有.
这是检查 MultipartFormDataContent
的 Content-Type 的示例:
multipart/form-data; boundary="85707dac-07d6-4978-8a35-32c09f6c5b7c"
但是,远程服务器期望边界值中没有引号,如下所示:
multipart/form-data; boundary=85707dac-07d6-4978-8a35-32c09f6c5b7c
为了解决这个问题,我删除了边界字段周围的双引号:
var contentType = multipartFormContent.Headers.ContentType.Parameters.First();
contentType.Value = contentType.Value.Replace("\"", String.Empty);
这个 Github 问题引起了我对边界值的关注:
https://github.com/dotnet/aspnetcore/issues/41237
这个 post 是我从边界中删除双引号的解决方案:
我正在尝试 POST 使用 HttpClient (.NET 6.0) 和 MultipartFormDataContent
的特定文件,但我不断收到以下错误:Error while copying content to a stream
但是,当通过Postman或通过服务器自己的门户网站上传文件时,它是成功的。不幸的是,我无法访问远程服务器,无法知道它失败的原因。
下面是删除了一些信息的示例代码。
public static class Program {
private static HttpClient client;
private static HttpClientHandler httpClientHandler;
private static async Task Main() {
httpClientHandler = new HttpClientHandler() {
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
client = new HttpClient(httpClientHandler);
client.BaseAddress = new Uri("https://remoteServerIpAddress/");
var filePath = "absoluteFilePath";
var fileBytesArray = File.ReadAllBytes(filePath);
var multipartFormContent = new MultipartFormDataContent();
multipartFormContent.Add(new ByteArrayContent(fileBytesArray));
// Setup headers for authorization
// Error occurs here
var uploadResponse = await client.PostAsync("api/upload", multipartFormContent).ConfigureAwait(true);
Console.WriteLine(await uploadResponse.Content.ReadAsStringAsync());
}
}
下面是错误的堆栈跟踪:
System.Net.Http.HttpRequestException
HResult=0x80131620
Message=Error while copying content to a stream.
Source=System.Net.Http
StackTrace:
at System.Net.Http.HttpContent.<<CopyToAsync>g__WaitAsync|56_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.MultipartContent.<SerializeToStreamAsyncCore>d__23.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.HttpContent.<<CopyToAsync>g__WaitAsync|56_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpConnection.<SendRequestContentAsync>d__68.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.HttpConnection.<SendAsyncCore>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Net.Http.HttpConnection.<SendAsyncCore>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpConnectionPool.<SendWithVersionDetectionAndRetryAsync>d__83.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Program.<Main>d__2.MoveNext() in C:\Projects\UploadApplication\Program.cs:line 59
Inner Exception 1:
IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host..
Inner Exception 2:
SocketException: An existing connection was forcibly closed by the remote host.
我见过类似的 post,但没有看到任何对我的情况有帮助的解决方案:
我不确定问题是否出在我的代码中,但如果有任何想法或想法,我们将不胜感激。
我们在之前的项目中遇到过这个问题。对我们有用的是使用需要 name
和 fileName
参数的 add 方法的重载之一。
multipartFormContent.Add(new ByteArrayContent(fileBytesArray), "name", "fileName")
我已经确定了问题,事实证明 MultipartFormDataContent
默认在边界值周围添加双引号,而服务器 Web 门户和 Postman 没有.
这是检查 MultipartFormDataContent
的 Content-Type 的示例:
multipart/form-data; boundary="85707dac-07d6-4978-8a35-32c09f6c5b7c"
但是,远程服务器期望边界值中没有引号,如下所示:
multipart/form-data; boundary=85707dac-07d6-4978-8a35-32c09f6c5b7c
为了解决这个问题,我删除了边界字段周围的双引号:
var contentType = multipartFormContent.Headers.ContentType.Parameters.First();
contentType.Value = contentType.Value.Replace("\"", String.Empty);
这个 Github 问题引起了我对边界值的关注: https://github.com/dotnet/aspnetcore/issues/41237
这个 post 是我从边界中删除双引号的解决方案: