我有两个控制器如下:
[RoutePrefix("v1/user/something")]
public class SomethingsController : ApiController
{
[Route("{id}")]
[HttpGet]
[ResponseType(typeof(SomethingsViewModel))]
public async Task<IHttpActionResult> GetAsync([FromUri]int id)
{
}
}
[RoutePrefix("v1/user")]
public class UserController : ApiController
{
[Route("{id}")]
[HttpGet]
[Authorize(Roles = "Super Admin")]
public async Task<IHttpActionResult> GetByIdAsync([FromUri]int id)
{
}
}
现在通过查看上面的代码,我认为正在创建以下两条路线:
但不幸的是,由于某种原因,事实并非如此。尝试访问上述路线之一时,我不断收到以下异常消息:
找到了与URL匹配的多种控制器类型。如果多个控制器上的属性路由与请求的URL匹配,则会发生这种情 该请求找到了以下匹配的控制器类型:MyProject.Api.Controllers.UserController,MyProject.Api.Controllers.SomethingsController
请帮我弄清楚我可能做错了什么,或者我错过了哪些小细节。
答案 0 :(得分:3)
虽然他们的路线前缀不同,但他们的路线匹配。例如,v1/user/{id}
将匹配v1/user/something/{id}
,其中第一条路线中的id
参数arg将采用something/{id}
。
路由前缀和路由属性组合以创建添加到路由表的完整路由。
在这种情况下,您需要使用约束以更好地区分路线。
[RoutePrefix("v1/user/something")]
public class SomethingsController : ApiController {
[Route("{id:int}")]
[HttpGet]
[ResponseType(typeof(SomethingsViewModel))]
public async Task<IHttpActionResult> GetAsync([FromUri]int id) { ... }
}
[RoutePrefix("v1/user")]
public class UserController : ApiController {
[Route("{id:int}")]
[HttpGet]
[Authorize(Roles = "Super Admin")]
public async Task<IHttpActionResult> GetByIdAsync([FromUri]int id) { ... }
}
现在,int
约束something
不会被误认为UserController.GetByIdAsync
动作的有效参数
参考Attribute Routing in ASP.NET Web API 2: Route Constraints
路线约束
路径约束允许您限制路径中的参数 模板匹配。一般语法是“{parameter:constraint}”。 例如:
[Route("users/{id:int}"] public User GetUserById(int id) { ... } [Route("users/{name}"] public User GetUserByName(string name) { ... }
这里,只有在“id”段的情况下才会选择第一条路线 URI是一个整数。否则,将选择第二条路线。