Form key or value length limit 2048 exceeded

前端 未结 3 653
北荒
北荒 2020-12-16 23:20

I am using asp.net core to build API. I have a request that allow user to upload profile image using this code

 [HttpPost(\"{company_id}/updateLogo\")]
              


        
相关标签:
3条回答
  • 2020-12-16 23:53

    By default, ASP.NET Core enforces key/value length limit of 2048 inside FormReader as constant and applied in FormOptions as shown below:

    public class FormReader : IDisposable
    {
        public const int DefaultValueCountLimit = 1024;
        public const int DefaultKeyLengthLimit = 1024 * 2; // 2048
        public const int DefaultValueLengthLimit = 1024 * 1024 * 4; // 4194304
        // other stuff
    }
    
    public class FormOptions
    {
        // other stuff
        public int ValueCountLimit { get; set; } = DefaultValueCountLimit;
        public int KeyLengthLimit { get; set; } = FormReader.DefaultKeyLengthLimit;
        public int ValueLengthLimit { get; set; } = DefaultValueLengthLimit;
        // other stuff
    }
    

    Hence, you may create a custom attribute to explicitly set key/value length limit on your own by using KeyValueLimit and ValueCountLimit property (also ValueLengthLimit etc.):

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class RequestSizeLimitAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
    {
        private readonly FormOptions _formOptions;
    
        public RequestSizeLimitAttribute(int valueCountLimit)
        {
            _formOptions = new FormOptions()
            {
                // tip: you can use different arguments to set each properties instead of single argument
                KeyLengthLimit = valueCountLimit,
                ValueCountLimit = valueCountLimit,
                ValueLengthLimit = valueCountLimit
    
                // uncomment this line below if you want to set multipart body limit too
                // MultipartBodyLengthLimit = valueCountLimit
            };
        }
    
        public int Order { get; set; }
    
        // taken from /a/38396065
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var contextFeatures = context.HttpContext.Features;
            var formFeature = contextFeatures.Get<IFormFeature>();
    
            if (formFeature == null || formFeature.Form == null)
            {
                // Setting length limit when the form request is not yet being read
                contextFeatures.Set<IFormFeature>(new FormFeature(context.HttpContext.Request, _formOptions));
            }
        }
    }
    

    Usage example in action method:

    [HttpPost("{company_id}/updateLogo")]
    [RequestSizeLimit(valueCountLimit: 2147483648)] // e.g. 2 GB request limit
    public async Task<IActionResult> updateCompanyLogo(IFormFile imgfile, int company_id)
    {
        // contents removed for brevity
    }
    

    NB: If latest version of ASP.NET Core is being used, change property named ValueCountLimit to KeyCountLimit.

    Update: The Order property must be included on attribute class because it is a member of implemented interface IOrderedFilter.

    Similar issues:

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

    Request.Form throws exception

    0 讨论(0)
  • 2020-12-17 00:03

    This answer was really helpful, thanks. But since .Net Core 2.1 there are built-in attributes for this purpose, e.g. RequestFormLimitsAttribute or RequestSizeLimitAttribute

    0 讨论(0)
  • 2020-12-17 00:12

    For may case adding [DisableRequestSizeLimit] attribute solved error; this can be helpful when you are not sure about maximum count of request. This is formal documentation.

        [HttpPost("bulk")]
        [ProducesResponseType(typeof(IEnumerable<Entry>), (int)HttpStatusCode.Created)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        [ProducesResponseType((int)HttpStatusCode.InternalServerError)]
        [DisableRequestSizeLimit]
        public async Task<IActionResult> BulkCreateEntry([FromBody] IEnumerable<CreateStockEntryFromCommand> command)
        {
            // do your work
        }
    
    0 讨论(0)
提交回复
热议问题