Controller动作首先抛出AmbiguousMatchException,然后在删除一个后抛出NotImplementedException。

20 浏览
0 Comments

Controller动作首先抛出AmbiguousMatchException,然后在删除一个后抛出NotImplementedException。

我正在将一个较旧的API项目从.NET Framework 4.7.2迁移到.NET 5,并且我希望保留与现有项目相同的API签名以保持API兼容性。这证明很麻烦。(对于这个问题,忽略上下文;我只是提供它来解释为什么我不想像Zhi Lv建议的那样更改URL路由。)

.NET 5项目中的一个控制器具有以下操作的签名:

[HttpGet]

[Route("{processedId}")]

// 我之前也尝试过[Route("{processedId:int}")] -- EDIT:但是我忽略了当时发生了不同的异常。

public async Task> GetQuestionByProcessedId(int processedId)

当我尝试使用以下URL访问时:

https://localhost:12345/api/questions/2

...我收到以下错误:

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:

请求匹配到多个端点。匹配项:

My.Namespace.Api.Controllers.MyController.GetQuestionsForFolder(QuestionBuilder.Api)

My.Namespace.Api.Controllers.MyController.GetQuestionByProcessedId(QuestionBuilder.Api)

错误中提到的另一个控制器操作具有以下签名:

[HttpGet]

[Route("{folderId=folderId:Guid}")]

public async Task>> GetQuestionsForFolder(Guid folderId)

如果我注释掉引起“模糊匹配”错误的操作,并进行新的调用,我会收到...

System.NotImplementedException:方法或操作未实现。

如果我反过来注释掉预期的端点GetQuestionByProcessedId,并只留下GetQuestionsForFolder,同样会出现相同的错误。

请注意,我可以成功访问GetQuestionsForFolder端点(当它没有被注释掉时)使用以下URL:

https://localhost:12345/api/questions/?folderId=87654321-1234-1234-1234-123456789012

问题:

这些错误似乎相互冲突。一种情况下,我有太多的端点可以服务于GET请求。当我移除其中之一后,就一个都没有了。

如何让URL找到正确的控制器操作,并且为什么它会先看到两个端点,然后又一个都没有?

为了过于清楚,我知道我可以合并这些端点来解决此问题。我的问题是为什么我有两个端点捕获请求,然后当一个被移除时,一个都没有了。

0
0 Comments

在上述代码中,出现了一个问题,即“请求匹配了多个终点”。为了解决这个问题,可以为每个终点设置路由约束。例如,可以使用以下代码:

[HttpGet]
[Route("{processedId:int}")] // 参数为 int 类型,允许带有 int 参数的请求
public async Task GetQuestionByProcessedId(int processedId)
{
    return Ok("value: " + processedId.ToString());
}
[HttpGet]
[Route("{folderId=folderId:Guid}")] // 参数为 guid 类型,允许带有 guid 参数的请求
public async Task GetQuestionsForFolder(Guid folderId)
{
    return Ok("value: " + folderId.ToString());
}

此外,还可以在路由/请求 URL 中添加动作名称,代码如下:

[HttpGet]
[Route("getQuestionByProcessedId/{processedId}")] // 参数为 int 类型
public async Task GetQuestionByProcessedId(int processedId)
{
    return Ok("value: " + processedId.ToString());
}
[HttpGet]
[Route("getQuestionsForFolder/{folderId=folderId:Guid}")] // 参数为 guid 类型
public async Task GetQuestionsForFolder(Guid folderId)
{
    return Ok("value: " + folderId.ToString());
}

然后,请求 URL 如下所示:

https://localhost:44310/api/todo/getQuestionsForFolder/87654321-1234-1234-1234-123456789012
https://localhost:44310/api/todo/getQuestionByProcessedId/2

输出结果如下所示:

![enter image description here](https://i.stack.imgur.com/EUCvB.gif)

通过这样的设置,可以解决“请求匹配了多个终点”的问题。然而,在确保代码没有其他错误的情况下,才能确保它运行正常,不会引发异常。非常感谢你把我带回正确的方向!

0