I am wondering how I can validate the content-length BEFORE the request body is read by the model binder in ASP.NET Web Api.
I can do it in the Action but then it's a waste of resources because the stream has already been read?
var contentLength = Request.Content.Headers.ContentLength;
if (contentLength > 1024*1024*20)
{
throw new HttpResponseException(HttpStatusCode.RequestEntityTooLarge);
}
Is it ok to do it in an Action Filter?
If your are using Owin for hosting your API, and you want to globally apply this restriction to all requests, then you could make this check in a simple Owin middleware executed before Web API in your Owin pipeline:
app.Use(async (c, n) =>
{
var request = c.Request;
if (request != null)
{
string[] headerValues;
if (request.Headers.TryGetValue("Content-Length", out headerValues))
{
var lengthValue = headerValues.First();
if (Convert.ToInt64(lengthValue) > 1024 * 1024 * 20)
{
c.Response.StatusCode = (int)HttpStatusCode.RequestEntityTooLarge;
return;
}
}
}
await n.Invoke();
});
//app.UseWebApi(..)
If you need to restrict the Content-Length
in a more fine graded fashion, then your best option is to create an AuthorizationFilter
that is executed before the model binding in the Web API pipeline , as opposed to a generic ActionFilter
.
Something like this should work:
public class MaxContentLengthAttribute : AuthorizationFilterAttribute
{
private readonly long _maxContentType;
public MaxContentLengthAttribute(long maxContentType)
{
_maxContentType = maxContentType;
}
public override void OnAuthorization(HttpActionContext actionContext)
{
var contentLength = actionContext.Request.Content.Headers.ContentLength;
if (contentLength.HasValue && contentLength.Value > _maxContentType)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.RequestEntityTooLarge);
}
}
}
And in your controller:
[MaxContentLength(1024*1024*20)]
public void Post([FromBody]Foo value)
{
DoWork(value);
}
This way you can respond to the request before the content is read by the model-binder.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.