Asp.net web api 如何设置ASP.NET Web Api路由约束HTTP状态返回代码

Asp.net web api 如何设置ASP.NET Web Api路由约束HTTP状态返回代码,asp.net-web-api,asp.net-web-api2,asp.net-web-api-routing,Asp.net Web Api,Asp.net Web Api2,Asp.net Web Api Routing,我正在使用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)

我正在使用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);
    }
我想知道id何时与上面的约束冲突。1或11, 如何超越默认HTTP状态返回码404


非常感谢。

我认为正确的解决方案是检查控制器内部的约束(正如@aanund所建议的)。但是,如果希望在代码中保留路由约束并避免条件,则可以创建另一个具有相同路由但没有约束的动作控制器。如果未验证约束,将调用新的动作控制器:

[Route("Number/{id:int:min(2):max(10)}")]
public HttpResponseMessage GetNumber([FromUri] int id)
{
    Request.CreateResponse(HttpStatusCode.OK, id)
}

[Route("Number/{id}")]
public HttpResponseMessage GetNumber2([FromUri] int id)
{
    Request.CreateResponse(HttpStatusCode.PreconditionFailed);
}

移除路由上的约束,并在方法内部进行验证

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

[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);
}
[Route(“Number/{id})]//无约束
公共HttpResponseMessage GetNumber([FromUri]int-id)
{
return(id>1&&id<11)//在这里验证id范围
?Request.CreateResponse(HttpStatusCode.OK,id)
:Request.CreateResponse(HttpStatusCode.PremissionFailed);
}

您可以创建一个自定义路由约束,该约束将按照您的意愿检查最小值和最大值,另外还允许您在约束未正确满足的情况下指定
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;
    }
}
现在,您的路线可以如下所示:

public class MyController : ApiController
{
    [Route("Number/{id:int:rangeWithStatus(2, 10, PreconditionFailed)}")]
    public HttpResponseMessage GetNumber([FromUri] int id)
    {
        return Request.CreateResponse(HttpStatusCode.OK, id);
    }
}
在本例中,
Conflict
HttpStatusCode.Conflict
枚举的字符串表示形式,稍后将其转换为约束中的枚举值

通过这种设置,如果值不在[2,10]范围内,Web API基础设施将以409状态代码而不是默认的404响应

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