-
Notifications
You must be signed in to change notification settings - Fork 711
The "more specific route" priority rule is not honored #797
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
I get the basic gist of what's happening, but it's a bit difficult to debug in my head. Do you have the world's simplest repro that demonstrates the problem? I maybe to be able to help figure out where things when awry. SidebarI would recommend you use a custom convention. That would remove all the nasty Reflection stuff. There are a bunch of other rules for action methods that are not being observed. It might look something like: public sealed class MyConvention : IControllerConvention
{
private readonly IReadOnlyList<ApiVersion> supportedVersions;
private readonly ApiVersion obsoleteVersion;
public MyConvention(IReadOnlyList<ApiVersion> supportedVersions, ApiVersion obsoleteVersion)
{
this.supportedVersions = supportedVersions;
this.obsoleteVersion = obsoleteVersion;
}
public bool Apply(IControllerConventionBuilder controller, ControllerModel controllerModel)
{
controller.HasApiVersions(supportedVersions);
var actions = controller.Actions;
for (var i = 0; i < actions.Count; i++)
{
var action = actions[i];
if (action.Attributes.OfType<ObsoleteAttribute>().Any())
{
controller.Action(action.ActionMethod).MapToApiVersion(obsoleteVersion);
}
}
}
} |
Hello, Thx for the tip on the custom convention. Note that in my case I had to ensure the controller didn't have the ApiVersionNeutral attribute: public bool Apply(IControllerConventionBuilder controller, ControllerModel controllerModel)
{
if (!controllerModel.Attributes.OfType<ApiVersionNeutralAttribute>().Any())
{
// set the supported versions
controller.HasApiVersions(_supportedVersions);
// assign the obsolete version to the obsolete methods
foreach (ActionModel action in controllerModel.Actions)
{
if (action.Attributes.OfType<ObsoleteAttribute>().Any())
{
controller.Action(action.ActionMethod).MapToApiVersion(_obsoleteVersion);
}
}
return true;
}
return false;
} |
I'll take a look at your repro. Your approach should work here; however, API versioning looks for IApiVersionNeutral and IApiVersionProvider. Using attributes just happens to be one of the ways these can be applied. :) |
Thank you for the repro. This is indeed strange. This does have the appearance of a bug, but I'm not sure why it is happening - or rather why it hasn't been discovered before. This a common scenario. There is even an acceptance test for this exact scenario. There is some combination here that is different from that test case. Ultimately, this is happening because There are 2 possible immediate workarounds:
You should only have to do it for this case. It could apply to any other case where the route templates can overlap. |
Thanks. |
Uh oh!
There was an error while loading. Please reload this page.
I have a controller that supports 2 versions (Latest and Obsolete), and this controller contains these routes:
If I call sites/contracts with version Latest (from header) I expect this route to be called, but it is actually sites/{siteId}.
I know I can disambiguate with siteId:int but I don't see any reason why the "more specific route" wouldn't apply here.
My config (as is, in case I made some mistake):
Basically all the controllers support Latest and Obsolete versions, and [Obsolete] methods are mapped to the Obsolete version.
And the controller:
Note that setting Latest as the default version (
options.DefaultApiVersion = ApiVersion.Parse(ApiVersions.Latest);
) produces the same result.The text was updated successfully, but these errors were encountered: