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")]
public async Task<IActionResult> updateCompanyLogo(IFormFile imgfile,int company_id)
{
string imageName;
// upload file
if (imgfile == null || imgfile.Length == 0)
imageName = "default-logo.jpg";
else
{
imageName = Guid.NewGuid() + imgfile.FileName;
var path = _hostingEnvironment.WebRootPath + <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e6c2a6">[email protected]</a>"Imgs{imageName}";
if (imgfile.ContentType.ToLower().Contains("image"))
{
using (var fileStream = new FileStream(path, FileMode.Create))
{
await imgfile.CopyToAsync(fileStream);
}
}
}
.
.
but it keeps returning this exception: Form key or value length limit 2048 exceeded
The Request
http://i.imgur.com/25B0qkD.png
Update:
I have tried this code but it doesn’t work
services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue; //not recommended value
options.MultipartBodyLengthLimit = long.MaxValue; //not recommended value
});
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.”
Method 2
For my case adding the [DisableRequestSizeLimit] attribute solved error; this can be helpful when you are not sure about the maximum length 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
}
Method 3
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
Method 4
services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue;
options.MultipartBodyLengthLimit = int.MaxValue;
options.MultipartHeadersLengthLimit = int.MaxValue;
});
it solved my problem
Method 5
I’m on .Net6 and this is all I needed. (In my startup file inside ConfigureServices(services).)
services.Configure<FormOptions>(options =>
{
options.KeyLengthLimit = int.MaxValue;
});
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0