且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何解决请求与.Net Core Web Api中的多个终结点匹配的问题

更新时间:2023-02-15 12:55:53

您要尝试执行的操作是不可能的,因为这些操作是动态激活的。在框架知道动作签名之前,无法绑定请求数据(例如查询字符串)。只有遵循路线,它才能知道动作签名。因此,您不能使路由依赖于框架甚至还不了解的东西。

What you're trying to do is impossible because the actions are dynamically activated. The request data (such as a query string) cannot be bound until the framework knows the action signature. It can't know the action signature until it follows the route. Therefore, you can't make routing dependent on things the framework doesn't even know yet.

长而短,您需要以某种方式区分路由:其他静态路径或将 userId 用作路由参数。但是,您实际上并不需要在这里进行其他操作。默认情况下,所有操作参数都是可选的。因此,您可以拥有:

Long and short, you need to differentiate the routes in some way: either some other static path or making the userId a route param. However, you don't actually need separate actions here. All action params are optional by default. Therefore, you can just have:

[HttpGet("{menuId}/menuitems")]
public IActionResult GetMenuItemsByMenu(int menuId, int userId)

然后可以确定是否 userId == 0 (默认值)。在这里应该没问题,因为永远不会有ID为 0 的用户,但是您也可以考虑将参数设为可空,然后在 userId.HasValue 来代替,这更加明确。

And then you can branch on whether userId == 0 (the default). That should be fine here, because there will never be a user with and id of 0, but you may also consider making the param nullable and then branching on userId.HasValue instead, which is a bit more explicit.

如果愿意,还可以继续将逻辑分开,方法是利用私人方法。例如:

You can also continue to keep the logic separate, if you prefer, by utilizing private methods. For example:

[HttpGet("{menuId}/menuitems")]
public IActionResult GetMenuItems(int menuId, int userId) =>
    userId == 0 ? GetMenuItemsByMenuId(menuId) : GetMenuItemsByUserId(menuId, userId);

private IActionResult GetMenuItemsByMenuId(int menuId)
{
    ...
}

private IActionResult GetMenuItemsByUserId(int menuId, int userId)
{
    ...
}