-
Notifications
You must be signed in to change notification settings - Fork 714
Getting 404 instead of 400 with versioning in routes #1049
-
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
{
}
Beta Was this translation helpful? Give feedback.
All reactions
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
-
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 🐉 🐉 🐉 .
Beta Was this translation helpful? Give feedback.
All reactions
-
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.
Beta Was this translation helpful? Give feedback.