首页 > 解决方案 > 如何解决请求与 .Net Core Web Api 中的多个端点匹配的问题

问题描述

我注意到关于这个主题有很多类似的问题。

调用以下任何方法时出现此错误。

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:请求匹配多个端点。

但是,我无法找出解决问题的最佳实践。到目前为止,我还没有设置任何特定的路由中间件。

// api/menus/{menuId}/menuitems
[HttpGet("{menuId}/menuitems")]
public IActionResult GetAllMenuItemsByMenuId(int menuId)
{            
    ....
}

// api/menus/{menuId}/menuitems?userId={userId}
[HttpGet("{menuId}/menuitems")]
public IActionResult GetMenuItemsByMenuAndUser(int menuId, int userId)
{
    ...
}

标签: c#.net-coreasp.net-core-webapiasp.net-core-routing

解决方案


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

总而言之,您需要以某种方式区分路由:其他静态路径或制作userId路由参数。但是,这里实际上不需要单独的操作。默认情况下,所有操作参数都是可选的。因此,您可以只拥有:

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

然后你可以分支是否userId == 0(默认)。在这里应该没问题,因为永远不会有 id 为 的用户0,但您也可以考虑使参数为空,然后userId.HasValue改为分支,这更明确一点。

如果您愿意,还可以通过使用私有方法继续保持逻辑分离。例如:

[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)
{
    ...
}

推荐阅读