ASP.NET CORE,Web API:没有路由匹配提供的值

mae*_*lin 11 c# asp.net-mvc-routing .net-core api-versioning asp.net-core-webapi

我在asp.net core(web api)中的路由有一些问题.

我有这个控制器(简化):

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[Controller]")]
public class DocumentController : Controller
{

[HttpGet("{guid}", Name = "GetDocument")]
public IActionResult GetByGuid(string guid)
{
    var doc = DocumentDataProvider.Find(guid);
    if (doc == null)
        return NotFound();

    return new ObjectResult(doc) {StatusCode = 200};
}


[HttpPost]
public IActionResult Create([FromBody] Document doc)
{
    //... Creating Doc

    //Does not work   
    //var val = CreatedAtRoute("GetDocument", new {guid = doc.Guid.ToString("N")}, document);
    //or this: CreatedAtRoute("GetDocument", new { controller = "Document", guid = doc.Guid.ToString("N")}, document);

    var val = CreatedAtRoute("GetDocument", new { version = "1", controller = "Document", guid = doc.Guid.ToString("N")}, document);

    return val;
}
}
Run Code Online (Sandbox Code Playgroud)

如果我调用Create,则会创建文档并创建路由对象,但是我收到错误"No route匹配提供的值"并获得500状态.

我可以直接调用GetByGuid,没有任何问题.

我找不到任何针对asp.net核心的调试帮助(就像任何现有的路由调试器一样).

我将不胜感激任何帮助!

编辑 看起来这将是微软的版本控制包的错误..如果我定义修复路由/ api/v1/[控制器]它的工作.

但那对我来说不是解决方案.

Ver*_*ile 21

就我而言,这是一个复制/粘贴错误。该CreatedAtAction方法的操作名称参数错误。确保第一个参数(actionName参数)与操作名称(函数名称)匹配。更正后的代码如下所示:

在此输入图像描述

  • 但“actionName”参数适用于您可以检索 (GET) 刚刚创建的实体的操作。 (9认同)

小智 17

我知道这篇文章是 2017 年的,但我仍然遇到了同样的问题并最终到了这里。看起来你从未发现你的错误,我会写在这里给其他发现这篇文章的人。

问题是当你打电话时:

CreatedAtRoute("GetDocument", new { version = "1", controller = "Document", guid = doc.Guid.ToString("N")}, document);
Run Code Online (Sandbox Code Playgroud)

您告诉程序查找接收 3 个参数的“GetDocument”函数,在本例中为 3 个字符串,但您的实际“GetDocument”定义仅接收 1 个字符串,即您的“guid”:

[HttpGet("{guid}", Name = "GetDocument")]
public IActionResult GetByGuid(string guid)
{
    var doc = DocumentDataProvider.Find(guid);
    if (doc == null)
        return NotFound();

    return new ObjectResult(doc) {StatusCode = 200};
}
Run Code Online (Sandbox Code Playgroud)

所以为了让它工作,你应该像这样:

CreatedAtRoute("GetDocument", new { guid = doc.Guid.ToString("N")}, document);
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用 3 个字符串创建一个新的 get 方法,也许您必须将其命名为与“GetDocument”不同的名称。

希望这有助于下一个寻找这个的人:D

  • 我的愚蠢错误是与这里的参数名称(即“guid”)不一致。确保它们在调用 `createdAtRoute()` 时匹配! (3认同)

Mai*_*eck 16

ASP.net 核心 3

为什么会出现这个问题:

“作为解决dotnet/aspnetcore#4849和ASP.NET Core MVC 的一部分trims the suffix Async from action names by default。从 ASP.NET Core 3.0 开始,此更改会影响路由和链接生成。”

查看更多: https : //docs.microsoft.com/en-us/dotnet/core/compatibility/aspnetcore#mvc-async-suffix-trimmed-from-controller-action-names

正如@Chris Martinez 在此线程中所说:

更改的原因并非随意;它解决了一个不同的错误。如果您不受上述错误的影响,并且想继续像以前一样使用 Async 后缀。

怎么解决

重新启用它:

services.AddMvc(options =>
{
   options.SuppressAsyncSuffixInActionNames = false;
});
Run Code Online (Sandbox Code Playgroud)

您现在应该传递createActionName包含Async后缀的参数,如下所示:

return CreatedAtAction("PostAsync", dto)

  • 我在dot net 5.0上测试过。它有效,谢谢。 (4认同)
  • 非常感谢,在 .net6 上做了一些小改动;services.AddControllersWithViews(options => { options.SuppressAsyncSuffixInActionNames = false; }); (4认同)

mae*_*lin 8

我将回答我自己的问题:这是微软版本控制包中的一个错误,它很快就会修复.

https://github.com/Microsoft/aspnet-api-versioning/issues/18

  • 我刚刚遇到了同样的问题,尽管这不是由于错误引起的,而是我在`CreatedAtRoute("WrongActionMethodName", dto)`中给出了错误的名称。 (3认同)
  • 而且还没有修好 (2认同)

gan*_*lam 5

以防万一,如果您像我一样,不喜欢从任何内置的 ControllerX 基类继承,那么您可能会遇到这个问题,如果您使用以下语句

  new CreatedAtActionResult(nameof(GetBookOf),
            nameof(BooksController),
            new {id = book.Id.ToString("N")},
            book)
Run Code Online (Sandbox Code Playgroud)

这是因为上面语句中的第二个参数,期望我们传递不带Controller后缀的构造函数名称。

因此,如果你像下面这样改变,那么它会工作得很好。

  new CreatedAtActionResult(nameof(GetBookOf),
            "Books",
            new {id = book.Id.ToString("N")},
            book)
Run Code Online (Sandbox Code Playgroud)


小智 5

这对我有用...... https://www.josephguadagno.net/2020/07/01/no-route-matches-the-supplied-values

我的异步获取是...

[HttpGet("{id}", Name = nameof(GetSCxItemAsync))]                            
public async Task<ActionResult<SCxItem>> GetSCxItemAsync(Guid id)
Run Code Online (Sandbox Code Playgroud)

但为了解决路由错误,我必须在函数声明之前添加以下内容......

[ActionName(nameof(GetSCxItemAsync))]
Run Code Online (Sandbox Code Playgroud)