-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
@Drakoumel opened this here: dotnet/core#805
Issue Title
The body of the receiving controller action of a multipart form data request is 0
General
So in short, I have two applications the FE and the API.
From the FE a user needs to upload a big file thus we use the code provided https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads
Ajax -> FE -> API.
The Ajax to FE works fine, but the FE to API send 0 body length. Although their controllers use the exact same code from the ms link.
On the API receiving end I see the following (see exception)
I do not know why this happens.
'section.Body.ReadTimeout' threw an exception of type 'System.InvalidOperationException'
Following is the code I use.
FileStream targetStream = System.IO.File.Create(targetFilePath);
await section.Body.CopyToAsync(targetStream);
Console.WriteLine($"Copied the uploaded file '{targetFilePath}'");
if (await _api.UploadFile(id, contentDisposition.FileName.Trim('"'), targetStream))
{
return BadRequest("Failed to upload file");
}
which on its own calls
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _session.AuthenticationToken());
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
form.Add(content, "fileToUpload");
content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = fileName
};
form.Add(content);
Upon sending the stream has Body length.
But upon receiving on the API it is empty.
[HttpPost("{id}")]
[DisableFormValueModelBinding]
public async Task<IActionResult> Upload()
{
string displayUrl = HttpContext.Request.GetDisplayUrl();
var arrayUrl = displayUrl.Split('/');
string metricId = arrayUrl.ToList().Last();
if (!this.IsMultipartContentType(Request.ContentType))
{
return BadRequest($"Expected a multipart request, but got {Request.ContentType}");
}
string targetFilePath = null;
var boundary = this.GetBoundary(
MediaTypeHeaderValue.Parse(Request.ContentType),
_defaultFormOptions.MultipartBoundaryLengthLimit);
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync(); <-- section.body = 0
}
I also tried with postman, which generated the code bellow ( I dont know which format is best )
curl -X POST \
http://localhost:5000/api/cloudstorage/08d4df1d-29a6-b421-9c77-df96f63c9f83 \
-H 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..hgj-C2Z4-ZcP6mDd7wIm7AVyWF0EzZwbvP6BIVzMKMs' \
-H 'cache-control: no-cache' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-H 'postman-token: 03f0b075-654d-2164-5f7c-bf1fa3277deb' \
-F 'file=@C:\Users\AAA\AppData\Local\Postman\app-5.1.2\content_resources_200_percent.pak'