代码之家  ›  专栏  ›  技术社区  ›  ruffin

控制器操作首先引发歧义匹配异常,然后在移除一个[sic]时引发NotImplementedException

  •  1
  • ruffin  · 技术社区  · 3 年前

    我正在从移植一个旧的API项目。NET Framework 4.7.2到。NET 5,我希望保留与现有项目相同的API签名,以保持API兼容性。事实证明这很麻烦。(对于这个问题,忽略上下文;我只是想说明为什么我不想更改URL路由 as Zhi Lv has suggested .)

    其中之一。NET 5项目的控制器具有以下签名的操作:

    [HttpGet]
    [Route("{processedId}")] 
    // I had also tried [Route("{processedId:int}")] -- EDIT: but missed that there was a different exception when I did. 🙄
    public async Task<TypedActionResult<Question>> GetQuestionByProcessedId(int processedId)
    

    当我尝试使用此URL访问时:

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

    …我收到以下信息:

    Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:
    The request matched multiple endpoints. Matches: 
    
    My.Namespace.Api.Controllers.MyController.GetQuestionsForFolder (QuestionBuilder.Api)
    My.Namespace.Api.Controllers.MyController.GetQuestionByProcessedId (QuestionBuilder.Api)
    

    该错误中提到的其他控制器操作具有以下签名:

    [HttpGet]
    [Route("{folderId=folderId:Guid}")]
    public async Task<TypedActionResult<IEnumerable<Question>>> GetQuestionsForFolder(Guid folderId)
    

    如果我评论掉冒犯性的、“模棱两可”的匹配并打新电话,我会收到。。。

    System.NotImplementedException: The method or operation is not implemented.
    

    如果我通过注释掉预期的端点来翻转实验,则会出现相同的错误, GetQuestionByProcessedId ,并且只离开 GetQuestionsForFolder .

    注意,我 可以 成功访问 获取文件夹的问题 使用以下URL的端点(未注释时,natch):

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


    问题

    这些错误似乎有冲突。在一个案例中,我有 太多了 准备好为GET请求提供服务的端点。当我去掉其中一个时,我 没有 .

    如何使URL找到正确的控制器操作,以及 为什么它看到两个,然后没有看到?

    过于清楚地说,我知道我可能 merge the endpoints 以解决此问题。我的问题是,为什么我有两个端点获取请求,而当其中一个被删除时,却没有。

    0 回复  |  直到 3 年前
        1
  •  2
  •   Zhi Lv    3 年前

    请求与多个终结点匹配

    要解决上述错误,您可以设置 route constraint 对于每个端点。

    例如

        [HttpGet]
        [Route("{processedId:int}")] // the parameter is int type, allow the request with int parameter
        public async Task<IActionResult> GetQuestionByProcessedId(int processedId)
        {
            return Ok("value: " + processedId.ToString());
        }
    
        [HttpGet]
        [Route("{folderId=folderId:Guid}")] //the parameter is guid type, allow the request with guid parameter
        public async Task<IActionResult> GetQuestionsForFolder(Guid folderId)
        {
            return Ok("value: " + folderId.ToString());
        }
    

    结果如下:

    enter image description here

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

        [HttpGet]
        [Route("getQuestionByProcessedId/{processedId}")] // the parameter is int type
        public async Task<IActionResult> GetQuestionByProcessedId(int processedId)
        {
            return Ok("value: " + processedId.ToString());
        }
    
        [HttpGet]
        [Route("getQuestionsForFolder/{folderId=folderId:Guid}")] //the paramer is guid type
        public async Task<IActionResult> 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