我的web api服务设置了以下默认路由...
config.Routes.MapHttpRoute(
name: "DefaultControllerWithIdAndAction",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new {action = RouteParameter.Optional}
);
config.Routes.MapHttpRoute(
name: "DefaultPost",
routeTemplate: "api/{controller}",
defaults: new { action = "Post" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
);
config.Routes.MapHttpRoute(
name: "DefaultGetWithId",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Get" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
);
config.Routes.MapHttpRoute(
name: "DefaultPutWithId",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Put" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
);
config.Routes.MapHttpRoute(
name: "DefaultDeleteWithId",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Delete" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
);
config.Routes.MapHttpRoute(
name: "DefaultControllerWithAction",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = RouteParameter.Optional }
);
我在'UsersController'下有以下服务:
public UserDto Get(string id){}
[HttpGet]
public UserDto ByEmail(string email)
[HttpGet]
public bool IsEmailUnique(string email)
问题是当我尝试点击这三种服务中的任何一种时,我收到了“发现多个操作”错误。请求应从所有路由中选择最后一条路由并执行请求。
如果我要执行'/api/users/byemail?email=blah@blah.com',不应该知道'ByEmail'是动作并使用方法&动作,匹配正确的方法?我想我错过了什么。
答案 0 :(得分:0)
似乎您已将BeEmail和IsEmailUnique方法映射到GET操作,这导致找到多个操作。
由于您已经为命名操作设置了路径模板(DefaultControllerWithAction),因此您可以删除[HttpGet]属性。
在此之后,routetemplate“DefaultControllerWithAction”应该排除'/ api / users / byemail'就好了
修改的 似乎在同一个ApiController中混合传统和基于动词的路由存在问题。 这是记录here on codeplex,有一篇博客文章声称解决了这个问题(尚未测试): http://blog.appliedis.com/2013/03/25/web-api-mixing-traditional-verb-based-routing/
EDIT2:
刚刚对此进行了测试,Kip Streithorst的解决方案可以解决您的问题。
Step 1:hardcode a default value instead of specifying that action is optional. Step 2:decorate your "verb-based controllers with the hardcoded default action name
对于你的获取请求,这将是:
config.Routes.MapHttpRoute( name: "DefaultControllerWithAction", routeTemplate: "api/{controller}/{action}", defaults: new { action = "DefaultAction } ); config.Routes.MapHttpRoute( name: "DefaultGetWithId", routeTemplate: "api/{controller}/{id}", defaults: new { action = "Get" }, constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) } ); config.Routes.MapHttpRoute( name: "DefaultControllerWithIdAndAction", routeTemplate: "api/{controller}/{id}/{action}", defaults: new { action = "DefaultAction" } );
和
[ActionName("DefaultAction")] public UserDto Get(string id){} [HttpGet] public UserDto ByEmail(string email) [HttpGet] public bool IsEmailUnique(string email)