PLEASE NOTE: This question was asked in 2016. The original answer to this problem was to update the microsoft api versiong package. In the current days, the problem reoccurs, but for other reasons.
Original Question:
i have some problems with the routing in asp.net core (web api).
I have this Controller (simplified):
[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; } }
If i call Create, the document is created and the routing object was created but i get the error "No route matches the supplied values" and get a 500 status.
I can call the GetByGuid directly, without any problems.
I couldn't find any debugging help for asp.net core (like any existing routing debugger).
I would appreciate any help!
EDIT Looks like it would be a bug from microsoft's versioning package.. if i define the fix route /api/v1/[Controller] it's working.
But that's not a solution for me.
"As part of addressing dotnet/aspnetcore#4849, ASP.NET Core MVC
trims the suffix Async from action names by default
. Starting with ASP.NET Core 3.0, this change affects both routing and link generation."
See more: https://docs.microsoft.com/en-us/dotnet/core/compatibility/aspnetcore#mvc-async-suffix-trimmed-from-controller-action-names
As @Chris Martinez says in this thread:
The reason for the change was not arbitrary; it addresses a different bug. If you're not affected by said bug and want to continue using the Async suffix as you had been doing.
Re-enable it:
services.AddMvc(options => { options.SuppressAsyncSuffixInActionNames = false; });
You should now pass the createActionName
parameter including the Async
suffix like this:
return CreatedAtAction("PostAsync", dto)
I know this post is from 2017 but still i just faced the same problem and ended up here. And as it looks like you never found your mistake I'll write it here for anyone else that founds this post.
The problem is that when you call:
CreatedAtRoute("GetDocument", new { version = "1", controller = "Document", guid = doc.Guid.ToString("N")}, document);
You are telling the program to look for a "GetDocument" function that receives 3 parameters, in this case 3 strings but your actual "GetDocument" definition receives only 1 string that is your "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}; }
So for it to work you should have it like this:
CreatedAtRoute("GetDocument", new { guid = doc.Guid.ToString("N")}, document);
Another option would be to create a new get method with 3 strings and maybe you'll have to call it something different than "GetDocument".
Hope this helps the next one that comes looking for this :D
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With