如何在 ASP.NET MVC 路由中将自定义约束与 HttpMethodConstraint 结合使用?
我有一个仅接受此 URL 上的 POST 的控制器:
POST http://server/stores/123/products
POST 的内容类型应为 application/json
,因此这就是我的路由表中的内容:
routes.MapRoute(null,
"stores/{storeId}/products",
new { controller = "Store", action = "Save" },
new {
httpMethod = new HttpMethodConstraint("POST"),
json = new JsonConstraint()
}
);
其中 JsonConstraint
code> 是:
public class JsonConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return httpContext.Request.ContentType == "application/json";
}
}
当我使用该路由时,我收到 405 Forbidden:
The HTTP verb POST used to access path '/stores/123/products' is not allowed
但是,如果我删除 json = new JsonConstraint()
约束,它工作正常。有人知道我做错了什么吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想把它放在评论中,但空间不够。
编写自定义约束时,检查
routeDirection
参数并确保您的逻辑仅在正确的时间运行非常重要。该参数告诉您您的约束是在处理传入请求时运行,还是在某人生成 URL 时运行(例如当他们调用
Html.ActionLink
时)。在你的情况下,我认为你想把所有匹配的代码放在一个巨大的“if”中:
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":
我将调试 JsonConstraint 并查看内容类型是什么。
无论出于何种原因,它都可能不是
application/json
。我知道那是 RFC MIME 类型,但我见过一些其他类型(例如
text/x-json
),正如 上一个问题。另外,我从未见过 ContentType 约束,所以我有兴趣看看它是否有效。您是否尝试过使用其他 MIME 类型以防万一出现问题?
最后,我将创建一个通用的 ContentTypeConstraint,而不是只有一个 JsonConstraint。
更新:
我在使用 ContentTypeConstraint 代码的路由上组合了一个快速 WebRequest 方法,并且该方法似乎工作正常。
Enum
约束类
使用您的示例,这将被称为:
这是约束可重用的不仅仅是 JSON。此外,如果您在枚举类上使用描述属性,则可以取消 switch case。
I would debug the
JsonConstraint
and see what the content type is.It's possible that, for whatever reason, it may not be
application/json
.I know that that is the RFC MIME type, but I've seen a few others floating around in my time (such as
text/x-json
), as has been mentioned here in a previous question.Also, I've never seen a ContentType constraint, so I'd be interested to see if it works. Have you tried it with other MIME types just in case it's faulty?
And finally, rather than have just a single JsonConstraint, I'd create a generic ContentTypeConstraint.
Update:
I knocked together a quick WebRequest method on a route that uses the ContentTypeConstraint code, and that seems to work correctly.
Enum
Constraint class
This would be called, using your example, as:
This was the constraint is reusable for much more than just JSON. Also, the switch case can be done away with if you use description attributes on the enum class.