如何在ASP.NET MVC路由中使用HttpMethodConstraint的自定义约束?

Dan*_* T. 8 asp.net-mvc routing asp.net-mvc-routing

我有一个控制器只接受此URL上的POST:

POST http://server/stores/123/products
Run Code Online (Sandbox Code Playgroud)

POST应该是content-type application/json,所以这就是我在路由表中的内容:

routes.MapRoute(null,
                "stores/{storeId}/products",
                new { controller = "Store", action = "Save" },
                new {
                      httpMethod = new HttpMethodConstraint("POST"),
                      json = new JsonConstraint()
                    }
               );
Run Code Online (Sandbox Code Playgroud)

在哪里JsonConstraint:

public class JsonConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return httpContext.Request.ContentType == "application/json";
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用这条路线时,我得到了一个405 Forbidden:

The HTTP verb POST used to access path '/stores/123/products' is not allowed

但是,如果我删除json = new JsonConstraint()约束,它工作正常.有人知道我做错了什么吗?

Eil*_*lon 8

我把它放在评论中,但没有足够的空间.

编写自定义约束时,检查routeDirection参数并确保逻辑仅在正确的时间运行非常重要.

该参数告诉您在处理传入请求时是否正在运行约束,或者在某人生成URL时(例如在他们调用时Html.ActionLink)运行约束.

在你的情况下,我认为你想把所有匹配的代码放在一个巨大的"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;
    }
}
Run Code Online (Sandbox Code Playgroud)