2

I am trying to POST a specific file using HttpClient (.NET 6.0) and MultipartFormDataContent, but I keep getting the following error: Error while copying content to a stream

However, when uploading the file through Postman or through the server's own web portal, it was successful. Unfortunately I don't have access to the remote server to know why it is failing.

Below is the sample code with some information removed.

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()); } } 

Here is the following stacktrace of the error:

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. 

I've seen a similar post, but did not see any solution that would help with my situation:

Posting MultipartFormDataContent request with HttpClient gets Error while copying content to a stream

I am not sure if the problem is in my code, but any thoughts or ideas would be appreciated.

2 Answers 2

4

I've identified the issue, and it turns out MultipartFormDataContent is adding double quotes around the boundary value by default, while both the server web portal and Postman did not.

This is an example of what the Content-Type for MultipartFormDataContent would look like if inspected:

multipart/form-data; boundary="85707dac-07d6-4978-8a35-32c09f6c5b7c"

However, the remote server was expecting no quotes in the boundary value, like the following:

multipart/form-data; boundary=85707dac-07d6-4978-8a35-32c09f6c5b7c

To get around this problem, I've removed the double quotes around the boundary field with the following:

var contentType = multipartFormContent.Headers.ContentType.Parameters.First(); contentType.Value = contentType.Value.Replace("\"", String.Empty); 

This Github issue is what got my attention into looking at the boundary value: https://github.com/dotnet/aspnetcore/issues/41237

This post is where I got the solution to remove the double quotes from the boundary: https://stackoverflow.com/a/48371123

Sign up to request clarification or add additional context in comments.

Comments

0

We had this issue in a previous project. What worked for us was to use one of the overloads of the add method that required the name and fileName parameters.

multipartFormContent.Add(new ByteArrayContent(fileBytesArray), "name", "fileName") 

2 Comments

I gave it a try, but unfortunately I got the same error
I would advise to then take a look here: stackoverflow.com/questions/2582036/… Something about the IOException and SocketException are leading me to believe its a connection protocol issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.