-
Notifications
You must be signed in to change notification settings - Fork 704
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
ApiVersionLinkGenerator methods that don't take HttpContext argument don't generate links #753
Comments
You'd have to share some additional details and perhaps a code snippet, but I suspect that this is - in fact - the expected behavior. This capability was added to address the expectation of auto-magically filling the API version route parameter when versioning by URL segment. Only the I'm going to assume you must be attempting this outside of a HTTP request. In order for API versioning to provide the route parameter value on your behalf, it must occur within the context of HTTP request. There is no other information where the value can be derived from. The interesting part is that you mention you can make it work with IHttpContextAccessor. That seems to suggest that you are within a HTTP request, but you're trying to generate the link in a place where HttpContext is no longer available. The simplest way to make things work with the HttpContext is to provide the API version route parameter yourself. This was always required before this capability was introduced. For example, if you template were var url = Url.Action( nameof( Get ), new { id = 42, version = "1" } ); You'd either have to know the API version for the path your traversing or capture it via model binding (e.g. action parameter) or the You should be cognizant that route names are not API version-aware. If you're going to use this approach, then you'll need some type of naming convention such as This issue illustrates one more complication from versioning by URL segment. It's the least RESTful method. It's probably too late to change methods, but it's something to think about in the future. No other method of versioning suffers from this issue. |
Thanks for the quick and very helpful reply. As you guessed, it's too late to avoid URL segment versioning, I need it to maintain compatibility with current applications. I plan to migrate the API and use a Mime Type, but will need to make sure all clients are upgraded first. I am attempting to generate the route inside the context of an http request, so I can pass the http context explicitly for my work around. All I did was change:
to
routeValues is just a simple anonymous object: Would it make any sense to have ApiVersionLinkGenerator implicitly try to get an http context for the methods (GetPathByAddress and GetUriByAddress) Thanks again for the detailed explanation. I think the MSDN docs are a little vague on the fact that ambient values are only available when an HttpContext is explicitly passed to LinkGenerator, but that's clearly the intent and you're following that model here, which makes perfect sense. |
Glad that solved, or at least provided a path to a solution, for your issue. The ApiVersionLinkGenerator is only meant to be a decorator over the DefaultLinkGenerator. It is technically possible to inject the HttpContext via IHttpContextAccessor, but it would force the service registration and potentially breaks the expected behavior. As I understand it, the overloads that do not take HttpContext are meant to be generatable without it (presumably because all values are provided). For consistency and predictability, it's probably best to leave it. I agree the documentation is light on this stuff. Since everything is open source, I tend to spelunk the source over MSDN anymore. The source can't lie. 😉 I was wondering how One additional side note is that the route parameter names in most cases are user-defined. |
AddApiVersionRouteValueIfNecessary requires an HttpContext and is only called in methods that have one as an argument. It looks like this is intentional, but the result is that LinkGenerator doesn't return a value for calls that don't provide either:
My specific case is ApiControllers that are calling GetPathByRouteValues(routeName, values), but I think it applies more broadly.
Versions
Microsoft.AspNetCore.Mvc.Versioning, 5.0.0
Microsoft.AspNetCore.App, 5.0.0
I'm working around this by using IHttpContextAccessor to get and pass the HttpContext, but that may not work for everyone (if services.AddHttpContextAccessor isn't called). I can create a minimal project that reproduces this if that's helpful.
The text was updated successfully, but these errors were encountered: