I am trying to upload a large file to my ASP.net core/ASP.net mvc site, but keep on encountering HTTP 413 - request entity too large. Even when I try to update web.config, other things still break.
Does anyone have a cheat sheet for dealing with this?
I created an asp.net mvc application and tried to test it.
Often we only pay attention to the uploadReadAheadSize setting, but tests have proved that this cannot completely solve the problem, and there are other configurations that need to be configured. (Added based on Jack's answer)
In addition to setting the uploadReadAheadSize value larger, there are also maxAllowedContentLength and maxRequestLength. You need to modify all these three values, otherwise the 413 or Maximum request length exceeded error will still be displayed.
In my test results, the application can upload any type of file within 1GB.
This works for me. Set it in your web.config under the configuration section:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="999999999" />
</requestFiltering>
</security>
</system.webServer>
Here is my cheat sheet:
The max file size limit coming through from IIS is specified through the UploadReadAhaead parameter, which can be specified in web.config as so. In this case, the maximum is set to 1000485760 bytes
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Detailed"></httpErrors>
<serverRuntime uploadReadAheadSize="1000485760" />
<httpErrors errorMode="Detailed" />
<asp scriptErrorSentToBrowser="true"/>
</system.webServer>
<system.web>
<customErrors mode="Off"/>
<compilation debug="true"/>
</system.web>
</configuration>
This is grand, as long as this specifier actually works. You might need a different solution, say, if you are hosting locally with something other than IIS (like kestrel, or even IIS express.)
Sometimes this configuration section is locked as well, in which case it can be unlocked using the following command (run cmd as admin):
%windir%\system32\inetsrv\appcmd.exe unlock config -section:system.webServer/serverRuntime
This is also something to consider when setting up prod. In some cases, your configuration within web.config within your code for the uploadReadAheadSize can conflict with whatever is specified in your prod instance. For me, I ended up getting rid of my configuration within source control, and instead, set the uploadReadAhead value for prod during environment set up. I did this by running the command (in cmd as admin):
appcmd set config "https://example.com" /section:system.webserver/serverruntime /uploadreadaheadsize:500048576 /commit:apphost
appcmd set config "http://example.com" /section:system.webserver/serverruntime /uploadreadaheadsize:500048576 /commit:apphost
I also set uploadReadAheadSize within C:\inetpub\wwwroot\web.config on the prod server as well, so it looks something like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<serverRuntime uploadReadAheadSize="500485760" />
<!--If this line breaks, unlock the config by opening cmd as admin and running %windir%\system32\inetsrv\appcmd.exe unlock config -section:system.webServer/serverRuntime-->
</system.webServer>
</configuration>
This can also be set as per this screenshot:
[![enter image description here][1]][1]
Now that you've set this up, it's still entirely possible that your application breaks, giving you a 413 because even though IIS may be set up correctly, there are also upload limits within the .net core ecosystem which can throw an HTTP 414 error when handling large files. This is something I found out [here][2]
The TLDR of this is that you want to have the following code within your startup.cs -> configureServices()
services.Configure<IISServerOptions>(options => {
options.MaxRequestBodySize = int.MaxValue;
});
services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = int.MaxValue;
x.BufferBodyLengthLimit = int.MaxValue;
x.MultipartBoundaryLengthLimit = int.MaxValue;
});
Note that there is code in there for if you are hosting for kestrel rather than IIS, also
[1]: https://i.stack.imgur.com/yLHQQ.png
[2]: https://github.com/dotnet/aspnetcore/issues/20369#issuecomment-607057822
We have a multi-tenanted MVC app, meaning that exactly the same app is published to multiple IIS virtual directories / applications, and then the app its self works out who it is, and skins its self (css) accordingly.
This is all very well, but anything logged by ELMAH in our elmah database gets logged under the same applicationName, as this is pulled out of Web.Config elmah section below where everything would be logged as "MyappName" :
<configuration>
[...]
<elmah>
<security allowRemoteAccess="false" />
<errorLog
type="Elmah.SqlErrorLog, Elmah"
connectionStringName="elmah"
applicationName="MyappName" />
</elmah>
</configuration>
The question is therefore how to override the applicationName setting from web.config with something specific so we can distinguish errors for a given tenant web site.
As this is configurable within the web.config, ELMAH are already providing you with a way to specify the application name when the application is deployed to different locations - it's just a case of making use of it.
This would generally be something that you would manipulate as part of your deployment steps. If you are doing it manually then it's going to be a pain, but it could be easily manipulated by using a web.config transform.
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<elmah>
<errorLog applicationName="MyappName" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</elmah>
</configuration>
I wonder if the following might work, if you put the following into your Global.asax:
var service = ServiceCenter.Current;
ServiceCenter.Current = context =>
{
var connectionString = "YOUR CONNECTION STRING";
var container = new ServiceContainer(service(context));
var log = new SqlErrorLog(connectionString) { ApplicationName = "APP NAME HERE" };
container.AddService(typeof(ErrorLog), log);
return container;
};
I installed Elmah via nuget. It usually works will if I use an .edmx. However I am using a code-first DbContext. Elmah seems to be sending the emails but it doesn't log to the database.
Any idea what could be going wrong?
It will work just fine with code first. You do not need the ELMAH_ERROR table as a part of your context. As long as you ran the elmah SQL in your database and setup your config correctly it WILL log to the database. Please share your config code, it should look something like this (a small portion of the config):
<elmah>
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah-sqlserver" applicationName="YOUR_APPLICATION" />
<security allowRemoteAccess="yes" />
</elmah>
<connectionStrings>
<add name="elmah-sqlserver" connectionString="Data Source=YOUR_SERVER;User ID=YOUR_USER_ID;Password=YOUR_PASSWORD;Initial Catalog=YOUR_CATALOG;" providerName="System.Data.SqlClient" />
</connectionStrings>
I always get an error when running my MVC Project since I put
this code on my web.config file.
<roleManager defaultProvider="CustomRoleProvider" enabled="true" cacheRolesInCookie="false">
<providers>
<clear />
<add name="CustomRoleProvider" type="SM.MyRoleProvider" />
</providers>
</roleManager>
This is what my error looks like :
Configuration Error
Description: An error occurred during the processing of a
configuration file required to service this request. Please review the
specific error details below and modify your configuration file
appropriately.
Parser Error Message: This method cannot be called during the
application's pre-start initialization phase.
Please can someone tell me whats going on ?
Hi you must be go to in visual studio and go to path:
website tab -> ASP.NET Configuration ->security tab -> disabled role
I'm trying a 90 day free trial of azure. It is super easy to deploy/publish the website and create the database, but for some reason my tables are not being created in the database. I'm using entity framework 4.4(i believe) and code first migrations. I've read that azure uses its own connection string, but I went ahead and changed my connection strings as well. I Spent hours on this and I can't figure out what is wrong and why my tables are not being created. I deploy website, enable-migrations, add-migration, update-database, then publish with checking the checkbox for code-first. Maybe my connection string is wrong? Any help is greatly appreciated.
In 'MyProject.Web' web.config:
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=tcp:n98my***.database.windows.net,1433;Initial Catalog=slutips_db;User Id=****;Password=****;" />
</connectionStrings>
Then in 'MyProject.Data' app.config, where my datacontext.cs is held:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<contexts>
<context type="SeluCmpsTutorials.Data.DataContext">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion">
<parameters>
<parameter value="slutips_db"/>
</parameters>
</databaseInitializer>
</context>
</contexts>
</entityFramework>
Also I noticed even though all my connection strings are changed, when I add-migration and update-database, it still using the ./sqlexpress local database, how is that possible?
key gotcha to be aware of regarding sql azure connections: for userid it actually usually needs to be user id # server name - do would read youruserid#n98my*** in the connectionstring.
Also, not sure if you need the "tcp:" (not using it) and you may also want to add providerName="System.Data.SqlClient"
Does your db user have necessary permissions for database modification ?
How did you set up your user ?
Initially you should create login for Azure sql server, sometihing like this:
(execute following sql on your server master database, replace angle-brackets values with actual values)
CREATE LOGIN [<SomeServerLogin>] WITH PASSWORD=N'<somepassword>'
Then connect to your slutips_db database as admin and execute following sql
CREATE USER [<slutips_db_user>] FROM LOGIN [<SomeServerLogin>];
GO;
EXEC sp_addrolemember 'dbmanager', '<slutips_db_user>';
GO;
EXEC sp_addrolemember 'loginmanager', '<slutips_db_user>';
GO;
'dbmanager' role allows table creation\management.
'loginmanager' role enables creation of another users in current database (your slutips_db_user will be allowed to execute CREATE USER <slutips_db_user1> FROM LOGIN <SomeServerLogin1> clause
Edit1: Also - ensure that your connection string user have user#n98my*** (user#server) format.
If you follow this tutorial: https://www.windowsazure.com/en-us/develop/net/tutorials/web-site-with-sql-database/ It'll show you how to connect Visual Studio (2012 in the example, not sure if works for any others) with Azure - basically you want to log into the portal, and download the publishing credentials. This will contain your database connection string, which you can then use to push code first migrations up to Azure.
What it looks like you've done is manually added in properties to the app.config yourself. The way the publish works, it defines a local version in your .config file like thus:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
Then, when you publish, VS will auto-magically insert the required stuff into your .config - if I go and FTP to my web site and look at the generated .config file, you see this:
<contexts>
<context type="Web_App.Models.TrackSafeDb, Web App">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[Web_App.Models.TrackSafeDb, Web App], [Web_App.Migrations.Configuration, Web App]], EntityFramework, PublicKeyToken=*******************">
<parameters>
<parameter value="Web_App.Models.TrackSafeDb_DatabasePublish" />
</parameters>
</databaseInitializer>
</context>
</contexts>
So I'd try removing the extraneous stuff from your local app.config and re-publishing
Try adding encryption to your connection string...
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=tcp:n98my***.database.windows.net,1433;Initial Catalog=slutips_db;User Id=****;Password=****;Integrated Security=False;Persist Security Info=True;Encrypt=True" />
</connectionStrings>
what i did was go to my azure management portal.
clicked on databases.
went view connection strings and then copied those directly into my relevant config.
in my case its "release" config.
make sure that the web config transformations are enabled and working correctly.
also make sure you've enabled firewall access to each of the db's...
you have to click "enable connection through firewall" or something similar.
its in the db options on the portal.
After seeing this question for a few days, a couple of thoughts. First, is the name of your context is infact DefaultConnection. Entity Framework (in order to be used with the parameterless constructor) likes the connection string name to match the name of the context.
For instance, if your declare a new context variable as such:
var context = new MyEntities();
Then your connection string should be called MyEntities
<connectionStrings>
<add name="MyEntities" connectionString="Data Source=tcp:n98my***.database.windows.net,1433;Initial Catalog=slutips_db;User Id=****;Password=****;" />
</connectionStrings>
Second, are you 100% sure that there are no web.config transformation files and/or that you also properly updated the connection strings in those files?
Third, remember that upon deployment, any configuration file other than the web.config is essentially ignored. The executing assembly is the web application, not the data project or any others. Any configurations relating to EF setup and deployment should be located in the web.config file (like the snippet that you have in your data app.config)
I had the exact same problem and it was linked to my password containing '%' character.
I checked the resulting web.config on Azure connecting with ftp and the part of my password containing '95%a' turned to '95ยช' ... automagically. That might be a bug in the web deployment feature of azure, because the password was correct in my publish profile locally.
If indeed the resulting password to the DB is corrupted in the resulting connection string, you have to reset it :
From Windows Azure Management, in the SQL DATABASES tab, select the SERVERS list (not the DATABASE list) and click on your server
In the Dashboard, there is a link to reset the admin password
In visual studio, update the password in your publish profile's connectionString (Settings, Databases)
Make a change to the web.config (a real one, not a comment), or it won't be re-published
Publish, and on first use of the database, the migrations will be applied