-
Notifications
You must be signed in to change notification settings - Fork 711
MapToApiVersion not descovered but still able to hit the route #735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you share how you've configured |
@commonsensesoftware as requested
|
As expected, you have Something else that is strange is that you still have an action mapped to API You didn't say, but I assume the URL that is causing you unexpected results is |
@commonsensesoftware ty for the responds i will look further into it. On why there is still an action mapped to We apply the (deprecated)apiversions at each controller from sorth of configuration/environmentsetting
Then some kind of MapToApiVersionRangeAttribute that can add a range from/to or if no to defined to the max apiversion defined (need to change to support minior versions here still)
if we then had the HelloWordController configured like this
So for this to work i need the not formally declared versions no longer able to reach them. i can solve this on other ways ofcourse but i'm starting to guesse this is a wrong approach |
It sounds like you are trying to achieve Version Symmetry by applying uniform API versions, even when nothing has changed so that a client only uses a single API version. You can achieve that with a convention, but API Versioning provides a formal Conventions API where you can use a fluent API and/or define your own conventions. That will be more natural and be simpler to implement than trying to use IApplicationModelConvention. In truth, the action probably should not match. Unfortunately, the application model and routing policies are disconnected by design. The endpoint matcher policy doesn't know how an action was mapped to a particular API version; it just knows that it has some associated API version(s). The most it can infer is whether an API version is explicitly defined (for precedence) as in the case of To move the API version forward for symmetry, I can see how you would want to drive that with configuration. You shouldn't assume that you can easily remove implementation code without a change though. This is a similar problem to people using inheritance in controllers. You cannot uninherit an action across API versions. If you truly want to ignore something by way of convention, you'll have to try something else. There's a few ways that could be done:
It's also worth noting that the API Versioning metadata is computed upfront. This information cannot be refreshed without restarting the host application. That's by design. You are probably already aware of that, but I just thought I'd call it out. There are some things attractive about Version Symmetry, but if your APIs are not external customer facing, the juice is not worth the squeeze in my opinion. Even then you can define sensible groups of APIs and versions without them all being the same. Not every service in Azure or AWS has the version number. Food for thought. |
Looks like suggestion Moving to a pure convention-based model without using any attributes will likely be required to get the flexibility you want. Everything that can be done with attributes can be done with conventions, including MapToApiVersion. It's probably simpler to define your conventions using the fluent API. You can wrap it up in a custom convention if that makes it easier to manage. Ultimately, all of the controllers and actions that can be mapped are statically known (based on your description). Mapping things down to that action level without static types is possible, but not straight forward. That is information you'd have to provide in your configuration. |
Circling back around on this issue... I'm promoting it to a bug as it should not be possible to route to an action that is only mapped. I've come up with a solution, but it's trickier than expected. Essentially, if an action has some declaration of an API version, but there is no corresponding implementation found, then the action doesn't match. There's very little difference between declaring an API version and mapping an API version, but the key difference is that mapping is not discoverable. The previous implementation did not consider a scenario where everything matched up to the request, but there were actually no discoverable (e.g. implemented) corresponding versions. This behavior has actually lead to another bizarre edge case that I don't have a solution for. If an API version is, in fact, implemented, but is split across multiple controller types, it is technically possible to map/match API versions across the types. This just feels wrong and is almost certainly a developer mistake, but there's no real way to catch such a behavior. Things will only successfully execute if there is a single mapping. The case where this would most likely happen will be from copy and paste, which would be caught as runtime mistake due to multiple matches. I've never seen this happen, it's a very rare edge case, I can't see how anyone would want to do that on purpose, and - ultimately - it isn't technically wrong from filtering out a list of possible candidates. I prefer to clear the minefield of such things. Perhaps an analyzer in the future could help detect and warn about such possible misconfigurations. In rereading this issue, I realized there is another approach that might be easier for you. Rather than necessarily change API version mapping, you can simply filter out controllers altogether. In the default configuration and implementation, this is achieved via the In order for that approach to work, you'd want a type-per-controller without interleaving; otherwise, it's not possible to split things out. You could use the Hopefully that is useful to you. The suggestions I've previously suggested all still apply. The next patch will contain a fix for this issue so no one else runs into it. In the meantime, there are several alternatives that should lead you toward a working solution. |
Uh oh!
There was an error while loading. Please reload this page.
Please consider the following case.
Because version 1.0 is not defined on the controller in a ApiVersionAttribute it is not discovered a not declare an API version. Just like i want because from this moment on i don't want to support this version any longer. My swagger documentation that is dependen on the IApiVersionDescriptionProvider works correctly and is no longer generating documentation for version1. When i make a api call to version 2.1 and check the returned version headers there is also only the supported version 2.1 & the deprecated version 2.0. Just as I excpected.
But when i make a call to version 1.0 i still hit the endpoint and the apiversion still doesn't return 1.0 as a supported version. I was hoping this would return a 400 bad request with the "UnsupportedApiVersion" error message and with the headers descriping the versions 2.0&2.1.
The reason i was exploring this behavior is that we want to make it possible to upgrade our microservice versions through adding the ApiVersionAttribute for certain version at runtime through some configuration. So we don't need to make a new build because the Getdefault route will be mapped for those higher apiversions.
The text was updated successfully, but these errors were encountered: