【问题标题】:Form submit resulting in "InvalidDataException: Form value count limit 1024 exceeded."表单提交导致“InvalidDataException:超出表单值计数限制 1024”。
【发布时间】:2016-11-16 08:40:59
【问题描述】:

我已经创建了一个 mvc 站点,并且我正在发布大量的 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 中读取这些值。 但是,我不知道应该在哪里设置这些设置。

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

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

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

【问题讨论】:

  • large amount of json form data 是什么意思?您是以application/x-www-form-urlencoded 内容类型还是application/json 发布数据?
  • @KiranChalla 我正在使用 Content-Type:application/x-www-form-urlencoded

标签: .net asp.net-mvc asp.net-core-3.1 asp.net-core-1.0 appsettings


【解决方案1】:

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

可以从 Startup.cs 设置限制:

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

见下图,我在一个请求中传递了 200 个参数。默认限制为 1024,但我已将其设置为 199,因此我传递了超过 199 个参数,然后它会报错。

【讨论】:

    【解决方案2】:

    使用 .net core 3.1 你还需要

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

    还有

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

    在这里找到:https://stackoverflow.com/a/64500089/14958019

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

    【讨论】:

      【解决方案3】:

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

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

      Link to official docs

      【讨论】:

        【解决方案4】:

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

        感谢andrey-bobrovcomment 中指出这一点。原始答案如下,供后人参考。


        您可以使用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)
        

        【讨论】:

        • 上面的代码解决了这个问题,但我认为新的 MVC 核心中的变量名已经更新。 “ValueCountLimit”现在是“KeyCountLimit”变量。我发现上面代码的类型相同,变量名更正,新版本stepbystepschools.net/?p=1044
        • 已经在新版本的asp.net core中实现了,见commit:github.com/aspnet/Mvc/commit/…
        • @AndreyBobrov 这个增加安全吗?这与docs.microsoft.com/en-us/security-updates/securitybulletins/… 有关,其中增加帖子大小会增加被利用的机会。
        • 创建像 RequestFormSizeLimit 这样的自定义属性肯定可以,但想知道应该使用什么限制?如果有一个表单可以动态添加输入控件并进行后期调用以保存它们,则此限制会不断增加。那么有谁知道最大值是多少,或者我应该说更安全的限制(对于.net core 2.0 和 Angular7 SPA 站点)?谢谢!
        • 属性RequestSizeLimitAttribute 在 ASP.NET Core 1.1 中不可用吗?
        【解决方案5】:

        在我的例子中,它通过更改 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
            });
        

        【讨论】:

        • 这对我来说在 Dotnet Core 2.1 中工作得很好!非常感谢:-)
        【解决方案6】:

        默认formvalue(not formkey)限制为1024。

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

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

        【讨论】:

        • 这非常适合我使用 asp.core。在startup.cs文件中找到,改成services.Configure(x => x.ValueCountLimit = 8192);
        • 这是一个很好的答案,因为它是全局设置的,而不是单独的方法。
        猜你喜欢
        • 2021-05-21
        • 1970-01-01
        • 1970-01-01
        • 2011-12-10
        • 2021-09-02
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多