【发布时间】:2019-09-18 04:46:03
【问题描述】:
我们正在为所有的 web api 路由使用特定的路由属性。
我们想要拆分一个控制器类,所以我们将一些更新功能移到一个单独的控制器类中。 我们随后遇到了一个奇怪的路由情况。
原来的控制器类是这样的:
[RoutePrefix("activities")]
public class ActivitiesController : ApiController
{
...
[Route("{activityId:int:min(1)}"), HttpPut]
public void Put(int activityId, [FromBody] NewActivity value) {}
[Route("{activityId:int:min(1)}"), HttpGet]
public dynamic Get(int activityId) {}
...
}
然后我们拆分更新,所以我们最终得到:
[RoutePrefix("activities")]
public class ActivitiesUpdateController : ApiController
{
...
[Route("{activityId:int:min(1)}"), HttpPut]
public void Put(int activityId, [FromBody] NewActivity value) {}
...
}
[RoutePrefix("activities")]
public class ActivitiesController : ApiController
{
...
[Route("{activityId:int:min(1)}"), HttpGet]
public dynamic Get(int activityId) {}
...
}
如果我们随后尝试调用任一端点: - PUT 活动/42 - 获取活动/42
我们得到错误:
Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.
The request has found the following matching controller types:
API.Controllers.ActivitiesUpdateController
API.Controllers.ActivitiesController
如果两个端点属于同一个类(新的或旧的),则一切正常。 不同的类会引发错误。
如果我使用 ApiExplorer 转储端点,则两个端点都是它们应该在的位置,并且不会在另一个类中重复,因此没有明显的重复。
我尝试过重命名函数、显式路由(即 ~/activities/:id)、添加 HttpGet 和 HttpPut 似乎没有什么不同。
这是一个奇怪的“特性”,即具有不同方法的相同端点必须在同一个类中?
没有意义。
【问题讨论】:
-
无意义,因为错误令人困惑;大多数人认为路线和方法是独一无二的,即 GET 活动/:id 与 PUT 活动/:id 不同。它仅使用路由来定位控制器并忽略方法,当您习惯将 Put(int id) 与 Get(int id) 作为不同的 C# 函数时,这是没有意义的。如果要完全限定路由,则必须对匹配的每条路由都进行此操作,这在有很多路由时有点痛苦,如果添加新端点很容易忘记。我们希望将其拆分以用于注入和可测试性目的。
-
总之,一切都好,现在有了解决方案。