I did encounter a wierd problem with kestrel. I am not able to upload the multiple files which exceed the kestrel's MaxRequestBodySize.
The expected behaviour is to throw the BadHttpRequestException when I am trying to reader this.Request.Form.Files.GetFiles(). I do expect to recieve request to controller action only once.
What is happening is that the upload action is hit a few time and browser with message "conection lost". I did not find a patter on how mamy times the action is called.
Controller action:
[HttpPost("upload")]
public IActionResult Upload()
{
try
{
var files = this.Request.Form.Files.GetFiles("files");
files.Select(async file => await this.SaveFile(file))
return this.RedirectToAction(nameof(VueController.FilesList),"Vue");
}
catch (BadHttpRequestException exp)
{
return new string[]
{
exp.Message
};
}
}
view:
<form method="post"
enctype="multipart/form-data"
action="/api/v1/files/upload"
novalidate="novalidate">
<input type="file"
name="files"
multiple="multiple"
required="required"
accept=""
capture="capture" />
</form>
asp.net core logs:
info: Microsoft.AspNetCore.Server.Kestrel[17] Connection id "0HLDB9K94VV9M" bad request data: "Request body too large." Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Request body too large. at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame.ThrowRequestRejected(RequestRejectionReason reason) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.ForContentLength.OnReadStart() at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.TryInit() at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.d__24.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.d__2.MoveNext() info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 7618.6319ms 413
Edited I am aware that I can disabled the limit but it is not possible in this case.
You must configure two things:
In your Program.cs
public static IWebHost BuildWebhost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options => {
options.Limits.MaxRequestBodySize = null; // or a given limit
})
.Build();
In your Startup.cs in the ConfigureService method
services.Configure<FormOptions>(options => options.MultipartBodyLengthLimit = long.MaxValue); // or other given limit
Also change your controller endpoint to use [FromForm]
public IActionResult Upload([FromForm] IEnumerable<IFormFile> files)... // name must be same as name attribute of your multipart form
Now ASP.NET Core will do the work and inject the files from the form as sequence.
Edit:
I created an example that can be cloned from github:
git clone https://github.com/alsami/example-fileupload-aspnet-core.git
cd example-fileupload-aspnet-core
dotnet restore
dotnet run --project src/file-upload-api/file-upload-api.csproj
Then navigate to http://localhost:5000/index.html and try uploading huge files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With