How do I use a custom constraint with a HttpMethodConstraint in ASP.NET MVC routing?
asp.net-mvc, asp.net-mvc-routing, routes
Solution
I'd put this in a comment but there isn't enough space.
When writing a custom constraint it is very important to inspect the `routeDirection` parameter and make sure that your logic runs only at the right time.
That parameter tells you whether your constraint is being run while processing an incoming request or being run while someone is generating a URL (such as when they call `Html.ActionLink`).
In your case I think you want to put all your matching code in a giant "if":
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.IncomingRequest) {
// Only check the content type for incoming requests
return httpContext.Request.ContentType == mimeType;
}
else {
// Always match when generating URLs
return true;
}
}
Problem
I have a controller that only accepts a POST on this URL: ``` POST http://server/stores/123/products ``` The POST should be of content-type `application/json`, so this is what I have in my routing table: ``` routes.MapRoute(null, "stores/{storeId}/products", new { controller = "Store", action = "Save" }, new { httpMethod = new HttpMethodConstraint("POST"), json = new JsonConstraint() } ); ``` Where `JsonConstraint` is: ``` public class JsonConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { return httpContext.Request.ContentType == "application/json"; } } ``` When I use the route, I get a 405 Forbidden: `The HTTP verb POST used to access path '/stores/123/products' is not allowed` However, if I remove the `json = new JsonConstraint()` constraint, it works fine. Does anybody know what I'm doing wrong?