I have written a custom route but found that its called for Action methods which have not specified the constraints in the attribute routing.
[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;
}
}
And added it in
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("checkGuid", typeof(CheckGuidRouteConstraint));
config.MapHttpAttributeRoutes(constraintResolver);
Now when I access the Put() method, the route constaraint's Match() method is called more than 1 times and finally fails. Please note that I haven't mentioned any route constraint in my Put() attribute route.