为什么ASP.NET Web API的POST请求会命中已定义的GET接口方法?
问题原因
ASP.NET Web API 约定路由的匹配逻辑是按注册顺序从上到下逐一匹配,只要匹配到符合路由模板的规则就会终止匹配,不会继续向下校验后续路由:
- 你注册的两个路由
routeTemplate完全一致,且都没有配置HTTP方法约束,所有发往application/apply路径的请求,不管是GET还是POST,都会优先命中第一个注册的ApplicationGet路由,强制绑定到标记了[HttpGet]的GetApplicationFunc方法。 - 该方法仅允许GET请求访问,所以POST请求到达时就会直接返回405状态码,根本不会走到第二个
ApplicationPost路由的匹配逻辑。
解决方案
方案1:为约定路由增加HTTP方法约束
在注册路由时通过HttpMethodConstraint限制每个路由仅能匹配对应的HTTP方法,调整后的路由注册代码如下:
routes.MapHttpRoute( name: "ApplicationGet", routeTemplate: "application/apply", defaults: new { controller = "Employee", action = "GetApplicationFunc"}, constraints: new { httpMethod = new System.Web.Http.Routing.HttpMethodConstraint(HttpMethod.Get) }); routes.MapHttpRoute( name: "ApplicationPost", routeTemplate: "application/apply", defaults: new { controller = "Employee", action = "PostApplicationFunc"}, constraints: new { httpMethod = new System.Web.Http.Routing.HttpMethodConstraint(HttpMethod.Post) });
方案2:改用属性路由(更简洁)
属性路由可以直接在接口方法上声明路由规则,避免约定路由的顺序问题,操作步骤如下:
- 首先在
WebApiConfig.cs中开启属性路由支持:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 开启属性路由 config.MapHttpAttributeRoutes(); // 其他原有配置... } }
- 直接在控制器方法上标记路由属性,无需再注册上述的约定路由:
public class EmployeeController : ApiController { [HttpGet] [Route("application/apply")] public object GetApplicationFunc([FromUri]EmployeeApplicationDTO request) { //Do GET specific stuff } [HttpPost] [Route("application/apply")] public object PostApplicationFunc([FromBody]EmployeeApplicationDTO request) { //Do totally different POST stuff } }
内容的提问来源于stack exchange,提问作者GitGotGood
相关产品推荐
相关产品推荐

