Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Getting 404 instead of 400 with versioning in routes #1049

Discussion options

I'm currently updating our .Net API from .Net 6 with Microsoft.AspNetCore.Mvc.Versioning v5.0.0 to .Net 8 with Asp.Versioning.Mvc v7.1.0. So far everything has been pretty straight forward but running into an issue with invalid versions throwing 404 errors instead of 400. With v5 this all worked as expected but after moving to the latest verison, it seems to hit routing prior to checking for bad versions. On a test, I downloaded the example projects and got the same behavior so I'm not certain if this is as intended or a bug. If I switch my API to use the query string versioning, everything works as expected. Outside of creating a custom middleware to pull routes and compare versions manually, I can't figure out a way to duplicate the behavior from the previous version.

Startup.cs (API has been upgraded since from 3.1)

services.AddProblemDetails();
services.AddApiVersioning(options =>
{
    options.ReportApiVersions = true;
    options.UnsupportedApiVersionStatusCode = 400;
}).AddMvc(options =>
{
    options.Conventions.Add(new VersionByNamespaceConvention());
}).AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'VVV";
    options.SubstituteApiVersionInUrl = true;
});

Controllers

[Route("api/crm/v{version:apiVersion}/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = "securitySchema")]
public class AccountController : BaseController
{
}
You must be logged in to vote

Unfortunately, this is a fundamental change in aligning to all of the routing behaviors. This is called out in the migration guide and was previously mentioned in the release notes.

This wasn't a decision taken lightly, but there was no way around it. Not fixing the routing meant that 406 and 415 did not work properly. Without going way down into the weeds, the reason that it no longer matches/works is because the API version is part of route resolution now. If an API version doesn't match, it's very hard, if not impossible to know if the rest of the path might match in the route tree. The routing system doesn't really have a way to skip matching a route parameter temporarily to see if th…

Replies: 1 comment · 1 reply

Comment options

Unfortunately, this is a fundamental change in aligning to all of the routing behaviors. This is called out in the migration guide and was previously mentioned in the release notes.

This wasn't a decision taken lightly, but there was no way around it. Not fixing the routing meant that 406 and 415 did not work properly. Without going way down into the weeds, the reason that it no longer matches/works is because the API version is part of route resolution now. If an API version doesn't match, it's very hard, if not impossible to know if the rest of the path might match in the route tree. The routing system doesn't really have a way to skip matching a route parameter temporarily to see if the rest will match later. I had a hack to make it work in the past, but it breaks other scenarios. This situation only applies to versioning by URL segment, which is one of the many reasons I do not recommend that style of versioning. I understand you've already chosen a path and cannot undo it now.

One possible alternative would be to create custom middleware that only looks for 404. It's simple to test whether there was a resolved API version. The easiest way is:

var resolvedVersion = httpContext.GetRequestedApiVersion() is not null;

Using the combination of 404 with a specified API version, you can decide if the URL could match and convert to 400 instead. Beyond that, I'm not sure how else to resolve this challenge.


Sidebar: API Versioning releases with affinity to ASP.NET Core. 5.0 matches to .NET 5, 6.0 matches .NET 6, and so on. .NET 8 support is in the works. I expect to release by week's end 🤞🏽. Be advised that using a version other than the target version of .NET is not guaranteed to work. Issues are rare, but I have seen/encountered them. Beware. There be 🐉 🐉 🐉 .

You must be logged in to vote
1 reply
@patrickabernathy
Comment options

I appreciate it. I had a feeling this was the case but I never saw it spelled out (or completely missed which is highly probable) so figured I'd ask before going down the rabbit hole. Was creating a middleware that read my Swagger routes and to see if other versions existed but I'll take a look at your proposed way as well. I did see that your current version was for .Net 7 but since 7 is in STS I went ahead and upped to 8 noting that a version for full support was coming. Thanks again.

Answer selected by patrickabernathy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.