簡體   English   中英

ASP.NET CORE、Web API:沒有路由與提供的值匹配

[英]ASP.NET CORE, Web API: No route matches the supplied values

請注意:這個問題是在 2016 年提出的。這個問題的原始答案是更新 microsoft api versiong 包。<\/strong> 目前,該問題再次出現,但出於其他原因。<\/strong>

原始問題:


我在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);
    // neither this
    var val = CreatedAtRoute("GetDocument", new { version = "1", controller = "Document", guid = doc.Guid.ToString("N")}, document);

    return val;
}
}

我知道這篇文章是 2017 年的,但我仍然遇到了同樣的問題並最終到了這里。 看起來你從未發現你的錯誤,我會寫在這里給其他發現這篇文章的人。

問題是當你打電話時:

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

您告訴程序查找接收 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};
}

所以為了讓它工作,你應該像這樣:

CreatedAtRoute("GetDocument", new { guid = doc.Guid.ToString("N")}, document);

另一種選擇是使用 3 個字符串創建一個新的 get 方法,也許您必須將其命名為與“GetDocument”不同的名稱。

希望這有助於下一個尋找這個的人:D

ASP.net 核心 3

為什么會出現這個問題:

“作為解決dotnet/aspnetcore#4849問題的一部分, ASP.NET Core MVC trims the suffix Async from action names by default刪除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;
});

您現在應該傳遞包含Async后綴的createActionName參數,如下所示:

return CreatedAtAction("PostAsync", dto)

我會回答我自己的問題:這確實是微軟版本控制包中的一個錯誤,很快就會修復。

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

我只是使用 return CreatedAtAction("ActionMethodName", dto); 相反,直到他們修復該錯誤。

發生此錯誤的另一個原因是 b/c,當您使用CreatedAtAction返回201 ,ASP.NET 將向響應添加一個Location標頭,其中包含可以訪問資源的 url。 它使用actionName來執行此操作,因此方法名稱需要與控制器上的有效方法匹配。 例如:

return CreatedAtAction("GetUser", new { id = user.UserId }, user);

如果GetUser不存在,調用將失敗。 更好的做法可能是使用:

return CreatedAtAction(nameof(GetUser), new { id = user.UserId }, user);

開發指南apidocs

我有同樣的症狀,但原因是別的。 基本上它不喜歡我的操作方法以Async結尾的事實。 當我將操作方法​​從GetAsync重命名為Get或將[ActionName("GetAsync")]添加到操作時,它會起作用。

來源: https : //github.com/microsoft/aspnet-api-versioning/issues/601

以防萬一,如果你像我一樣,不喜歡繼承任何內置的 ControllerX 基類,那么你可能會遇到這個問題,如果你使用以下語句

  new CreatedAtActionResult(nameof(GetBookOf),
            nameof(BooksController),
            new {id = book.Id.ToString("N")},
            book)

這是因為上面語句中的第二個參數,期望我們傳遞沒有Controller后綴的構造函數名稱。

因此,如果你像下面這樣改變,那么它會工作得很好。

  new CreatedAtActionResult(nameof(GetBookOf),
            "Books",
            new {id = book.Id.ToString("N")},
            book)

這對我有用...... 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)

但是為了解決路由錯誤,我必須在函數聲明之前添加以下內容...

[ActionName(nameof(GetSCxItemAsync))]

取而代之的是:

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

將您的退貨更改為以下內容:

return CreatedAtRoute("GetDocument",doc, null);

我將把這個貼在這里給其他一些可憐的不幸的靈魂,因為我花了太長時間弄清楚我做錯了什么。

這是錯誤的:

app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute());

這樣做是通過返回默認路由[controller]來掩蓋問題,當您希望它返回的是[controller]\\{newly generated id}

這是對的:

return CreatedAtAction(nameof(GetUser), new { id = user.UserId }, user);

但是有一個邊緣情況會失敗,這是當user.UserIdnull 我認為這會失敗,因為需要id參數,所以不能為null ,因此路由沒有綁定。 它失敗是件好事,因為如果沒有,那么您將創建一個垃圾路由,但錯誤消息可能比它可能更神秘。

在我的例子中,我返回的是輸入對象上的 Id,它是空的,而不是輸出對象上新生成的 Id。

在我的情況下,這是一個復制/粘貼錯誤。 CreatedAtAction方法具有錯誤的操作名稱參數。 確保第一個參數( actionName參數)與操作名稱(函數名稱)匹配。 更正后的代碼如下所示:

在此處輸入圖片說明

您必須為如下方法命名並返回

    [HttpGet("{id}",Name = "MethodName")]
    public async Task<IActionResult> MethodName(int id)
    {
        var baseItem = await _baseItemService.BaseItemByIdAsync(baseItemId);
        return Ok(baseItem);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM