Form submit resulting in “InvalidDataException: Fo

2019-02-16 10:15发布

问题:

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.

回答1:

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)


回答2:

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;
    });
}


回答3:

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
    });