Open RehanSaeed opened 5 years ago
I agree. This should be less cumbersome. I don't care if it's IUrlHelper or IUrlGenerator, as long as it is fully setup by the DI system as part of ASP.NET.
LinkGenerator requires the HttpContext to generate a URL.
This is not true. LinkGenerator is specifically designed to work without an HTTP context.
See: https://github.com/aspnet/AspNetCore/blob/master/src/Mvc/Mvc.Core/src/Routing/ControllerLinkGeneratorExtensions.cs#L84 and similar methods.
As far as I can work out this is not true for absolute URL's containing the scheme, host and port. Using this code:
this.linkGenerator.GetPathByRouteValues("GetPage", new { First = 1, Last = 10 });
Outputs:
/foo?first=1&last=10
@RehanSaeed - can you provide some more information? I'm not sure how I'm supposed to draw a conclusion from that.
I want to generate absolute URL's with the full scheme, host and optionally a port i.e. https://example.com/foo?bar=1
. Why? Well, one reason is that in API's a full URL is much easier to consume from JavaScript.
Today, if you want to do this, you have to have the HttpContext
and pass it into the LinkGenerator
or IUrlHelper
as I've shown in my code samples above. This is used to pull the scheme and host from the current request and stick it into the URL.
That's all well and good in a controller where you have easy access to the HttpContext
. However, if I'm outside of the controller and want to generate a URL, then if I use LinkGenerator
, then I am forced to also inject IHttpContextAccessor
or if I'm using IUrlHelper
, it's possible to avoid injecting IHttpContextAccessor
but you have to add some additional setup in Startup
and use an extension method. All code is shown above.
Both of these solutions are noisy and require extra work, just to get an absolute URL. Ideally, I'd want a method that does all of that for me and allows me to generate URL's without all the extra noise and ceremony.
Does that clear things up?
I agree with RehanSaeed. I had the need to generate absolute urls in a module that sends out emails to clients (which is outside the web project). I only want the IUrlHelper or LinkGenerator as dependency and don't want to do all the IHttpContextAccessor setup as described above.
I want to generate absolute URL's with the full scheme, host and optionally a port i.e. https://example.com/foo?bar=1. Why? Well, one reason is that in API's a full URL is much easier to consume from JavaScript.
This is something we can work with. Do you actually care about the current request? Or do you just want it to be easier to generate absolute URLs?
I can imagine a feature where you can centrally configure a default scheme and host that will be used in URLs - or it could fallback to the listening address if nothing is configured and there is only one listening address.
There reason I'm making this distinction is that passing in the "current request" does more than just set up scheme/host/pathbase - it also includes ambient route values. Trying to make a service that will magically use ambient values from the current request is a recipe for failure because it's going to do different things depending on which route reached the current thing.
I don't care about the current request at all, I'm just forced to care to generate a URL based on the current requests scheme, host and URL.
I can imagine a feature where you can centrally configure a default scheme and host that will be used in URLs - or it could fallback to the listening address if nothing is configured and there is only one listening address.
I could get behind such a feature. The fallback sounds like the correct default with the option to override it.
That sounds good to me as well!
Great, I'm sticking this in the 5.0 milestone so it will get looked at.
We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.
I have a requirement to use the LinkGenerator to generate links outside of a Web Project, similar to the requirement mentioned by @FilipVanBouwel earlier in this issue.
My requirement is to use the LinkGenerator in a worker process that runs in its own process, with no web host configured.
The only way I have been able to achieve this so far is as follows. Are there any issues with using this method? Is there a simpler approach that I am overlooking?
1) In the ConfigureServices of the application, register the controllers from the web project with MVC
var apiAssembly = Assembly.GetAssembly(typeof(RouteNames));
services.AddMvcCore()
.AddApplicationPart(apiAssembly)
.AddControllersAsServices();
2) At the end of ConfigureServices I create an application builder and use this to map the controllers with Endpoint Routing. My application does not build a web host, so the endpoints below should never be accessible. I only perform this step as without it I don't believe that the LinkGenerator will be aware of the MVC Routes.
// Map the controllers as endpoints to allow the LinkGenerator to link to controller routes.
var appBuilder = new ApplicationBuilder(serviceProvider);
appBuilder.UseRouting();
appBuilder.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
3) I can then inject a LinkGenerator into my HostedService and generator links as follows:
var path = _linkGenerator.GetPathByName("MyRouteName", new { });
Thanks for contacting us.
We're moving this issue to the .NET 8 Planning
milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
Is your feature request related to a problem? Please describe.
LinkGenerator
LinkGenerator
requires theHttpContext
to generate a full absolute URL which also contains the scheme, hostname and optional port. Outside of the controller, this means I have to also inject theIHttpContextAccessor
into my constructor and pass it in like so:This requires a lot of ceremony and additional noise.
IUrlHelper
IUrlHelper
does not require theHttpContext
if you add this code to theStartup
. We use theIActionContextAccessor
andIUrlHelperFactory
to registerIUrlHelper
into the IoC container.Then if you use the following extension method to create your URL's:
Here is the usage:
I think you'll agree this is much nicer.
Describe the solution you'd like
I would like a way to generate URL's without having to inject the
IHttpContextAccessor
andLinkGenerator
just to generate a single URL. Or a way to useIUrlHelper
without all the setup code to get it working nicely.