如何设置ASP.NET Web Api路由约束HTTP状态返回码

juv*_*han 3 asp.net-web-api asp.net-web-api-routing asp.net-web-api2

我正在使用ASP.NET Web Api 2框架并使用如下的基本路由约束.

    [Route("Number/{id:int:min(2):max(10)}")]
    public HttpResponseMessage GetNumber([FromUri] int id)
    {
        return (id > 0)
            ? Request.CreateResponse(HttpStatusCode.OK, id)
            : Request.CreateResponse(HttpStatusCode.PreconditionFailed);
    }
Run Code Online (Sandbox Code Playgroud)

我想知道当id与上面的约束,.eg 1或11冲突时,如何覆盖默认的HTTP Status Return代码404?

非常感谢.

Fil*_*p W 8

您可以创建自定义路径约束,该约束将按照您的意愿检查最小值,最大值,并且还允许您指定HttpStatusCode在未正确满足约束的情况下.

public class RangeWithStatusRouteConstraint : IHttpRouteConstraint
{
    private readonly int _from;
    private readonly int _to;
    private readonly HttpStatusCode _statusCode;

    public RangeWithStatusRouteConstraint(int from, int to, string statusCode)
    {
        _from = from;
        _to = to;
        if (!Enum.TryParse(statusCode, true, out _statusCode))
        {
            _statusCode = HttpStatusCode.NotFound;
        }
    }

    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values,
        HttpRouteDirection routeDirection)
    {
        object value;
        if (values.TryGetValue(parameterName, out value) && value != null)
        {
            var stringValue = value as string;
            var intValue = 0;

            if (stringValue != null && int.TryParse(stringValue, out intValue))
            {
                if (intValue >= _from && intValue <= _to)
                {
                    return true;
                }

                //only throw if we had the expected type of value
                //but it fell out of range
                throw new HttpResponseException(_statusCode);
            }
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您需要在属性映射中注册它:

        var constraintResolver = new DefaultInlineConstraintResolver();
        constraintResolver.ConstraintMap.Add("rangeWithStatus", typeof(RangeWithStatusRouteConstraint));
        config.MapHttpAttributeRoutes(constraintResolver);
Run Code Online (Sandbox Code Playgroud)

你的路线现在看起来像这样:

public class MyController : ApiController
{
    [Route("Number/{id:int:rangeWithStatus(2, 10, PreconditionFailed)}")]
    public HttpResponseMessage GetNumber([FromUri] int id)
    {
        return Request.CreateResponse(HttpStatusCode.OK, id);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下Conflict,HttpStatusCode.Conflict枚举的字符串表示形式,稍后将其强制转换为约束中的枚举值.

使用此类设置,如果值超出[2,10]范围,则​​Web API基础结构将使用409状态代码而不是默认值404进行响应.


aan*_*und 5

删除路径上的约束,并在方法内执行验证.

约束用于确定是否应该使用路径,但是如果输入超出某些参数,则希望使用要命中的路径但更改状态代码.

[Route("Number/{id})] // No constraints
public HttpResponseMessage GetNumber([FromUri] int id)
{
    return (id > 1 && id < 11) // here you validate id range
        ? Request.CreateResponse(HttpStatusCode.OK, id)
        : Request.CreateResponse(HttpStatusCode.PreconditionFailed);
}
Run Code Online (Sandbox Code Playgroud)