表单提交导致 "InvalidDataException: Form value count limit 1024 exceeded."

Form submit resulting in "InvalidDataException: Form value count limit 1024 exceeded."

我已经创建了一个 mvc 站点,并且正在 post 处理大量 json 表单数据 (Content-Type:application/x-www-form-urlencoded) 回到 mvc 控制器。当我这样做时,我收到一个 500 响应,指出:“InvalidDataException:超出表单值计数限制 1024。”

在以前的 aspnet 版本中,您可以将以下内容添加到 web.config 以增加限制:

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

当我将这些值放入 web.config 时,我没有看到任何变化,所以我猜测 Microsoft 不再从 web.config 中读取这些值。 但是,我不知道应该在哪里设置这些设置。

非常感谢任何有关增加表单值计数的帮助!

需要说明的是,当我的 post 数据中的项目数少于 1024 时,此请求可以正常工作。

更新: 在 asp.net MVC Core 3.1 中,错误消息是 - “无法读取请求表单。超出表单值计数限制 1024。”

更新: MVC SDK 现在通过 RequestSizeLimitAttribute 包含此功能。不再需要创建自定义属性。

感谢andrey-bobrov for pointing this out in a 。原答案如下,供后人参考。


您可以使用 FormOptions 更改默认的表单值限制。如果您使用的是 MVC,那么您可以创建一个过滤器并装饰您想要扩展此限制并为其余操作保留默认值的操作。

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

动作:

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

注意:如果您的操作也需要支持防伪验证,那么您需要订购过滤器。示例:

// 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)

默认 formvalue(不是 formkey) 限制是 1024。

此外,我认为您可以更改 Startup.cs 文件中的 FormOptions 限制。

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

在我的例子中,它通过在 Startup.cs 文件

中更改 ValueLengthLimit 来工作
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
    });

如果您使用的是 .net core 2.1 或更高版本,则可以在控制器或操作上使用内置的 RequestFormLimits 属性,如下所示-

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

Link to official docs

对于 .net core 3.1,您还需要

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

还有

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

在此处找到:

只有 MaxModelBindingCollectionSize 我得到我的 json 对象超过 1024 行完全从 javascript 和 ajax 传递到 mvc 控制器。

表格数值计数限制基本上是总数没有。您在请求中传递的参数。

可以从Startup.cs设置限制:

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

见下图,我在一个请求中传递了200个参数。默认限制是 1024,但我将它设置为 199,所以我传递了超过 199 个参数,然后它会给出错误。

允许的表单条目数量的默认限制由 ValueCountLimit property of FormOptions. You can use the options pattern 控制以配置该值。

例如:

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

然后你可以定义一个配置节来定义一个新的值:

"Form": {
    "ValueCountLimit": 2048
  }

这提供了比 hard-coding 值更灵活的方法。您应该避免设置任意高的值,因为该限制有助于防止因提交非常大的表单而引起的拒绝服务攻击。

FormOptions的其他属性可以用同样的方法设置。省略的值将使用默认值。