1

我编写了一个自定义路由,但发现它调用了未在属性路由中指定约束的 Action 方法。

[RoutePrefix("api/v1/Orders")]
public class OrdersController : BaseController
{

    [Route("{orderId}/archive")]   
    public HttpResponseMessage Put(Guid orderId, [FromBody]List<ComplexObject> c)
    {

    }        

    public HttpResponseMessage Get([FromUri]ComplexObject c)
    {

    }        

[Route("{orderId:checkGuid(orderId,BadRequest)}/{personId:checkGuid(personId,BadRequest)}")]
    public HttpResponseMessage Get(Guid orderId, Guid personId)
    {

    }
}

public class CheckGuidRouteConstraint : IHttpRouteConstraint
{       
    private readonly HttpStatusCode _statusCode;
    private readonly string _parameterName;

    private HttpStatusCode _default = HttpStatusCode.BadRequest;

    public CheckGuidRouteConstraint(string parameterName,string statusCode)
    {
        if (!Enum.TryParse(statusCode, true, out _statusCode))
        {
            _statusCode = _default;
        }
        _parameterName = parameterName;
    }

    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
    {
        bool isRouteWrong = doSomeCheck();

        if(isRouteWrong)
        {                
            //throw custom exception with proper message
        }

        return true;
    }
}

并将其添加到

var constraintResolver = new DefaultInlineConstraintResolver();
        constraintResolver.ConstraintMap.Add("checkGuid", typeof(CheckGuidRouteConstraint));
        config.MapHttpAttributeRoutes(constraintResolver);

现在当我访问 Put() 方法时,路由约束的 Match() 方法被调用超过 1 次,最终失败。请注意,我没有在我的 Put() 属性路由中提到任何路由约束。

4

1 回答 1

0

如果您有许多具有相同方法的自定义 IHttpRouteConstraint 和控制器,则这种方法不起作用。似乎 WebAPI 没有解析路由参数,只是在任何已注册的 IHttpRouteConstraint 返回 true 之前尝试所有这些参数。因此,如果其中一个抛出异常,它会自动停止处理其他约束。如果首先注册了错误的约束,即使在路由模板中未使用此约束,您也会收到错误响应。

 [HttpGet]
    [Route("{code:enum(System.Net.HttpStatusCode)}")]
    public IHttpActionResult Enum(string code)
    {
        return Ok();
    }

    [HttpGet]
    [Route("{period:values(days|weeks|months)}")]
    public IHttpActionResult Value(string period)
    {
        return Ok();
    }

例如,如果“枚举”约束具有与您相同的类似实现并首先注册

 constraintsResolver.ConstraintMap.Add("enum", typeof(EnumConstraint));
 constraintsResolver.ConstraintMap.Add("values", typeof(ValuesConstraint));
 config.MapHttpAttributeRoutes(constraintsResolver);

价值操作永远不会返回 Ok。

于 2016-02-24T07:01:39.587 回答