Aspnetcore: Endpoint Routing incompatible with API versioning

Created on 7 Dec 2018  ·  8Comments  ·  Source: dotnet/aspnetcore

Describe the bug

UrlHelpers cannot locate routes when controller route contains api version.

InvalidOperationException: No route matches the supplied values.
Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)

Disabling Endpoint Router restores correct behaviour.

To Reproduce

Steps to reproduce the behaviour:

  1. Get attached reproduction: bug.zip
  2. Run the application
  3. Navigate to http://localhost:5002/Bar (SUCCESS)
  4. Navigate to http://localhost:5002/v1/Foo (FAIL)
  5. Toggle EnableEndpointRouting in startup (see .AddMvcCore(options => options.EnableEndpointRouting = true))
  6. Navigate to http://localhost:5002/v1/Foo (SUCCESS)
area-mvc

Most helpful comment

API Versioning 3.1 has been released and includes support for _Endpoint Routing_.

@AdamWillden unless you are continuing to observe issues, I believe this issue can now be closed.

cc: @Eilon

All 8 comments

There's a simpler reproduction (without swagger etc) by @vanbukin here: https://github.com/Microsoft/aspnet-api-versioning/issues/409

API Versioning 3.1 has been released and includes support for _Endpoint Routing_.

@AdamWillden unless you are continuing to observe issues, I believe this issue can now be closed.

cc: @Eilon

As the issue and fix is in aspnet-api-versioning I believe this can be closed. I'll raise issues over there if I observe issues.

Thanks for the mention and hard work to fix this @commonsensesoftware

Awesome, thanks Chris!

@commonsensesoftware when you next get a moment (no rush - it's Christmas 🎄)...

Can you download my reproduction from the first post, upgrade the package to 3.1.0 then navigate to http://localhost:5002/v1/Foo as instructed.

I'm still seeing the same issue. So, if you've now done your bit, there may be another issue somewhere else? Can you confirm I'm not being a moron please? Or anyone else...

I'll re-open this in the mean time (though perhaps the title will change).

Two basic issues:

  1. You're missing the API version route parameter in the link generation
  2. You need to change the route parameter name to a legal identifier (e.g. api-versionversion)

I changed your route template to: v{version:apiVersion}/[controller]. Updating the response is then trivial:

```c#
[HttpGet]
public IActionResult Create(ApiVersion apiVersion) =>
CreatedAtAction(new Bar { Baz = Guid.NewGuid() }, apiVersion);

private IActionResult CreatedAtAction(Bar bar, ApiVersion apiVersion)
{
return CreatedAtAction(
nameof(GetByIdAsync),
new { baz = bar.Baz, version = apiVersion.ToString() },
bar);
}
```

Model binding support for ApiVersion is new 3.0. Its source is _special_ because it can come for any number of locations, even multiple places within the same request or not from the request at all. Since you're versioning by URL segment, you'll need to include the version route parameter. Alternatively, if your controller class only supports a single version, you can simply hardcode the route parameter value (e.g. version = "1.0").

For your convenience, here's the fixed repro with the necessary changes. Merry Christmas!

Wow, that's really kind of you. I'll try this out once the wine wears off 🍷 ... Maybe Friday 🙄 . I'll close as you've obviously sorted this for me.

Was this page helpful?
0 / 5 - 0 ratings