我编写了一个自定义路由,但发现它调用的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()属性路由中没有提到任何路由约束。
答案 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);
价值行动将永远不会返回确定。