52

I have created an mvc site and I'm posting a large amount of json form data (Content-Type:application/x-www-form-urlencoded) back to the mvc controller. When I do this, I receive a 500 response that states: "InvalidDataException: Form value count limit 1024 exceeded."

In previous versions of aspnet, you would add the following to the web.config to increase the limit:

<appSettings>
    <add key="aspnet:MaxHttpCollectionKeys" value="5000" />
    <add key="aspnet:MaxJsonDeserializerMembers" value="5000" />
</appSettings>

When I put these values in the web.config, I do not see any change, so I'm guessing Microsoft is no longer reading these values out of the web.config. However, I cannot figure out where these settings should be set.

Any help with increasing the form value count is greatly appreciated!

To be clear, this request works perfectly fine when the number of items in my post data is less than 1024.

Update: In asp.net MVC Core 3.1 the error message is - "Failed to read the request form. Form value count limit 1024 exceeded."

Rahatur
  • 3,147
  • 3
  • 33
  • 49
Michiel Bugher
  • 1,005
  • 1
  • 7
  • 23
  • 2
    What do you mean by `large amount of json form data`? Are you posting data as `application/x-www-form-urlencoded` content type or `application/json`? – Kiran Jul 13 '16 at 18:02
  • @KiranChalla I am using Content-Type:application/x-www-form-urlencoded – Michiel Bugher Jul 13 '16 at 19:04

7 Answers7

84

The default formvalue(not formkey) limit is 1024.

Also, I think you can just change the FormOptions limit in Startup.cs file.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<FormOptions>(options =>
    {
        options.ValueCountLimit = int.MaxValue;
    });
}
Daniel Puiu
  • 962
  • 6
  • 21
  • 29
Viking
  • 841
  • 1
  • 6
  • 2
  • This worked perfect for me using asp.core. Found it in the startup.cs file and changed it to services.Configure(x => x.ValueCountLimit = 8192); – Smac Jun 27 '18 at 12:06
  • This is a good answer as its globally set, rather than individual method. – Ajay2707 Mar 19 '19 at 05:00
33

If you are using .net core 2.1 or above, you can use the built in RequestFormLimits attribute as shown below on a controller or action-

[RequestFormLimits(ValueCountLimit = 5000)]
public class TestController: Controller

Link to official docs

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
sankar
  • 807
  • 8
  • 11
27

Update: The MVC SDK now includes this functionality via RequestSizeLimitAttribute. There is no longer any need to create a custom attribute.

Thanks to andrey-bobrov for pointing this out in a comment. The original answer is below, for posterity.


You can change the default formvalue limit using the FormOptions. If you are using MVC, then you can create a filter and decorate on action where you want to extend this limit and keep the default for rest of the actions.

/// <summary>
/// Filter to set size limits for request form data
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequestFormSizeLimitAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
{
    private readonly FormOptions _formOptions;

    public RequestFormSizeLimitAttribute(int valueCountLimit)
    {
        _formOptions = new FormOptions()
        {
            ValueCountLimit = valueCountLimit
        };
    }

    public int Order { get; set; }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var features = context.HttpContext.Features;
        var formFeature = features.Get<IFormFeature>();

        if (formFeature == null || formFeature.Form == null)
        {
            // Request form has not been read yet, so set the limits
            features.Set<IFormFeature>(new FormFeature(context.HttpContext.Request, _formOptions));
        }
    }
}

Action:

[HttpPost]
[RequestFormSizeLimit(valueCountLimit: 2000)]
public IActionResult ActionSpecificLimits(YourModel model)

NOTE: If your action needs to support Antiforgery validation too, then you would need to order the filters. Example:

// Set the request form size limits *before* the antiforgery token validation filter is executed so that the
// limits are honored when the antiforgery validation filter tries to read the form. These form size limits
// only apply to this action.
[HttpPost]
[RequestFormSizeLimit(valueCountLimit: 2000, Order = 1)]
[ValidateAntiForgeryToken(Order = 2)]
public IActionResult ActionSpecificLimits(YourModel model)
radj
  • 4,360
  • 7
  • 26
  • 41
Kiran
  • 56,921
  • 15
  • 176
  • 161
  • The above code solves the problem but i think there has been updates in variable names in the new MVC core. "ValueCountLimit " is now ""KeyCountLimit " variable. I found the same type of above code with corrected variable names with new version http://stepbystepschools.net/?p=1044 – Shivprasad Koirala Nov 02 '16 at 04:45
  • 3
    it has been implemented already in the new version of the asp.net core, see commit: https://github.com/aspnet/Mvc/commit/17f6b17a6dc0e76606b091187a4e43a184656c89 – Andrey Bobrov Nov 16 '17 at 10:47
  • 1
    @AndreyBobrov is this safe to increase? This is in relation to https://learn.microsoft.com/en-us/security-updates/securitybulletins/2011/ms11-100 where increase post size increases chance of exploitation. – radj Oct 31 '18 at 10:25
  • Creating a custom attribute like RequestFormSizeLimit works for sure, but wondering what limit should be used?. If there is a form where you can add input controls dynamically and make a post call to save them, this limit keeps increasing. So does anyone know what is the max or should I say safer limit would be(for .net core 2.0 and Angular7 SPA site)? Thanks! – sankar Mar 29 '19 at 18:41
  • is the attribute `RequestSizeLimitAttribute` not available in ASP.NET Core 1.1? – LP13 May 23 '19 at 16:06
  • Also for .Net Core ASP you need services.Configure(options => { options.MemoryBufferThreshold = 1500000000; options.MultipartBodyLengthLimit = 1500000000; }); in your Startup.cs – Richard Keene May 05 '20 at 16:08
  • Works for Asp.net Core 3.1 as it is – Rahatur Mar 17 '21 at 06:25
23

In my case, it worked by changing ValueLengthLimit, in Startup.cs file

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<FormOptions>(options =>
    {
        options.ValueCountLimit = 200; // 200 items max
        options.ValueLengthLimit = 1024 * 1024 * 100; // 100MB max len form data
    });
Wagner Pereira
  • 1,050
  • 11
  • 11
9

With .net core 3.1 you need in addition to

services.Configure<FormOptions>(options =>
{
    options.ValueCountLimit = int.MaxValue;
});

also

services.AddMvc(options =>
{
    options.MaxModelBindingCollectionSize = int.MaxValue;
});

Found here: https://stackoverflow.com/a/64500089/14958019

Only with MaxModelBindingCollectionSize i get my json object with more than 1024 rows fully passed from javascript with ajax to mvc controller.

doppelff
  • 99
  • 1
  • 1
2

Form value count limit is basically total no. of parameters you passed in request.

Limit can be set from Startup.cs:

 services.Configure<FormOptions>(options =>
            {
                options.ValueCountLimit = 199;
            });

See image below, I have passed 200 parameters in a request. Default limit is 1024 but I have set it as 199 so I pass more than 199 parameters then It will gives an error.

enter image description here

enter image description here

prisan
  • 1,251
  • 12
  • 9
0

The default limit on the amount of allowed form entries is controlled by the ValueCountLimit property of FormOptions. You can use the options pattern to configure the value.

For example:

builder.Services.Configure<FormOptions>(configuration.GetSection("Form"));

You can then define a configuration section to define a new value:

"Form": {
    "ValueCountLimit": 2048
  }

This provides a more flexible approach than hard-coding the values. You should avoid setting an arbitrarily high value as the limit will help to prevent against denial of service attacks caused by submitting extremely large forms.

Other properties of FormOptions can be set using the same method. Omitted values will use the defaults.