ASP.NET Core 2.0 enforces 30MB (~28.6 MiB) max request body size limit, be it Kestrel and HttpSys. Under normal circumstances, there is no need to increase the size of the HTTP request. But when you are trying to upload large files (> 30MB), there is a need to increase the default allowed limit. In this short post, we’ll see how to increase file upload size in ASP.NET Core application and various options to control this restriction.
Increase file upload size in ASP.NET Core
If you are also looking for file upload solution in ASP.NET Core, here are some useful post.
- How to upload file via Swagger in ASP.NET Core Web API
- Uploading Multiple Files in ASP.NET Core Razor Pages
- How to upload a file from Angular 5 to ASP.NET Core 2.1 Web API
As we know ASP.NET Core applications are platform independent so you can host them on Windows, Linux or Mac platform. In other words, you may host the application on IIS, Ngnix and Apache web server. Kestrel is a cross-platform web server for ASP.NET Core and that’s included by default in ASP.NET Core project templates. Kestrel can be used as a standalone server or with a reverse proxy server, such as IIS, Nginx, or Apache.
There is no single solution which covers all deployment options to increase the request size limit. The solution differs based on the deployment options. We may have following deployment options,
- Hosted on IIS (with Kestrel or without Kestrel)
- Hosted on Kestrel (as standalone or with Ngnix and Apache server)
Hosted on IIS
Remember in the ASP.NET, we used to set maxRequestLength
in web.config file to increase the default limit of 4MB. Like,
<configuration> <system.web> <httpRuntime maxRequestLength="xxx" /> </system.web> </configuration>
Similarly, for ASP.NET Core application, we can increase the default limit of 30MB by setting maxAllowedContentLength
property in the web.config
file. The default ASP.NET Core application template doesn’t create the web.config
file. It is created when you publish the application. However, you can also add it manually (if not present) to the root of the application with the following code.
<?xml version="1.0" encoding="utf-8"?> <configuration> <!-- To customize the asp.net core module uncomment and edit the following section. For more info see https://go.microsoft.com/fwlink/?linkid=838655 --> <system.webServer> <handlers> <remove name="aspNetCore"/> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/> </handlers> <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" /> <security> <requestFiltering> <!-- This will handle requests up to 50MB --> <requestLimits maxAllowedContentLength="52428800" /> </requestFiltering> </security> </system.webServer> </configuration>
You are required to define maxAllowedContentLength
in the security section. You can read more about the web.config
file for ASP.NET Core here.
In order to create the reverse proxy between IIS and the Kestrel server, the web.config file must be present at the content root path (typically the app basepath) of the deployed app. This is the same location as the website physical path provided to IIS. This setting only applies to IIS.
Hosted on Kestrel (as standalone or with Ngnix and Apache server)
Starting in ASP.NET Core 2.0.0, Kestrel server also imposes its own default limits. There are 3 different ways to increase this default limit.
-
MVC Solution
If you want to change the max request body size limit for a specific MVC action or controller, you can use the
RequestSizeLimit
attribute. Like,[HttpPost] [RequestSizeLimit(40000000)] public async Task<IActionResult> UploadFiles(IFormFile file) { //TODO: Save file }
It sets the maximum allowed request length for this action method. You can apply this attribute at action level or controller level. This is the recommended approach to increase the limit in an ASP.NET Core MVC app.
There is another attribute
DisableRequestSizeLimit
applicable at the controller level or the action level to disable the size limit on the HTTP request. This will set the request limit to unlimited. Like,[HttpPost] [DisableRequestSizeLimit] public async Task<IActionResult> UploadFiles(IFormFile file) { //TODO: Save file }
-
Global solution
To modify the max request body size globally, set
MaxRequestBodySize
option for Kestrel. Like,public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseKestrel(options => { options.Limits.MaxRequestBodySize = 52428800; //50MB }); }
This applies to any request for the entire application. The
MaxRequestBodySize
is a nullable long. Setting it to null disables the limit. Now you might be thinking why this doesn’t work for windows as IIS also uses Kestrel. The reason is, this setting is disabled for Kestrel running behind IIS where the normal web.config limit is applied. Though this is a global setting, it can be overridden on per-request basis via middleware. -
Middleware solution
If you want to override the global setting based on a request basis, you can do it via middleware. This allows you to modify individual requests through some flexible configuration. Like,
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder => { context.Features.Get<IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize = null; //TODO: take next steps });
Remember, this cannot be changed after the reading the request body has started. An exception is thrown if you try to configure the limit on a request after the app has started to read the request. There’s an
IsReadOnly
property that indicates if theMaxRequestBodySize
property is in a read-only state, meaning it’s too late to configure the limit.
That’s it.
Summary
To summarize, this post provides the solution to increase the request limit size for ASP.NET Core application, covering all possible deployment options. Based on your deployment model, you are required to make configuration changes. Though, it would be ideal to have a single solution to increase the request limit, irrespective of the deployment option. Let’s hope things will change, but for now, we’ll have to follow this.
Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.
In the middleware solution, line 4 produces an error:
The name ‘context’ does not exists in the current context
Why?
Does the middle ware solution help us upload more than 4gb data in asp.net core running on IIS?
ok but 50MB is not large enough what about 5GB file? i know this is not common
If you are using …Blazor (SignalR limit)… increment MaximumReceiveMessageSize
services.AddSignalR(e => {
e.MaximumReceiveMessageSize = 102400000;
})
More info: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.signalr.huboptions.maximumreceivemessagesize
Great, thank you for sharing this article!
HelpFul Article
Thank’s
Solved perfectly my problem with .net core 2.2 on centos
THANK YOU!
What kind configuration I should do in launchsettings.json?
Greeting
I have question if I apply any of these way I can upload until 1 GB ???
Yes. you can
Does not work. I tried all solutions.
context.Features.Get
Are you getting any error?
You’re probably running on IIS Express.. I had a same problem.. Change your launchsettings or first you can try to run .exe file from bin folder if it works.
What kind configuration I should do in launchsettings.json?
Hi PER.
Did you solve the problem?
I have same problem that we tried all solutions but still not working.
If you solved the problem, please tell me. Thanks!
Not resolved, but a little more explanation …:
The Code:
app.UseWhen(context => context.Request.Path.StartsWithSegments(“/api”), appBuilder =>
{
context.Features.Get().MaxRequestBodySize = null;
//TODO: take next steps
});
Cannot compile, because ‘context’ is not part of the second lambda expression. However you can rewrite it like:
app.UseWhen(context => context.Request.Path.StartsWithSegments(“/api”), appBuilder =>
{
appBuilder.ServerFeatures.Get().MaxRequestBodySize = null;
//TODO: take next steps
});
However, appBuilder.ServerFeatures is always null …