多次调用自定义路径约束,或者在根本没有提到约束时调用

时间:2016-01-18 18:13:50

标签: asp.net-mvc asp.net-web-api asp.net-mvc-routing attributerouting route-constraint

我编写了一个自定义路由,但发现它调用的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()方法时,路径constaraint的Match()方法被调用超过1次,最后失败。 请注意,我的Put()属性路由中没有提到任何路由约束。

1 个答案:

答案 0 :(得分: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();
    }

例如,如果'enum'约束具有与您的相同的实现并且首先注册

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

价值行动将永远不会返回确定。