在模型绑定ASP.NET Web Api之前验证内容长度

时间:2016-04-19 08:47:57

标签: c# asp.net asp.net-mvc asp.net-web-api

我想知道如何在ASP.NET Web Api中的模型绑定器读取请求主体之前验证内容长度。

我可以在Action中执行此操作但是这会浪费资源,因为该流已经被读取了?

var contentLength = Request.Content.Headers.ContentLength;
if (contentLength > 1024*1024*20)
{
     throw new HttpResponseException(HttpStatusCode.RequestEntityTooLarge);
}

可以在动作过滤器中执行吗?

1 个答案:

答案 0 :(得分:2)

如果您使用Owin来托管您的API,并且您希望将此限制全局应用于所有请求,那么您可以在Owin管道中的Web API之前执行的简单Owin中间件中进行此检查:

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(..)

[编辑]

如果您需要以更精细的分级方式限制Content-Length,那么您最好的选择是创建一个{strong} {<1}},然后执行模型绑定{{ 3}},而不是通用的AuthorizationFilter

这样的事情应该有效:

ActionFilter

在你的控制器中:

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

这样,您可以在模型绑定器读取内容之前响应请求。