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?
We can apply the multiple constraints to a parameter by a colon (:) separator. [Route(URLPath/{parameterName: constrain:Constrain:….})] In the preceding example, the route will only be selected if the parameter id is an integer as well as a value of id greater than 1000.
Implement the IRouteConstraint Match method in ASP.NET Core To create a custom route constraint, you should create a class that extends the IRouteConstraint interface and implements its Match method.
aspx file Register Route method. //Custom Route With Regular Expression Constraints routes. MapRoute( "Blog", "Archive/{entrydate}", new { Controller = "Blog", action = "Archive" }, new { entryDate = @"\d{2}-\d{2}-\d{4}" });
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With