Injection of IUrlHelper in ASP.NET Core
Solution 1
.NET Core 3+ and .NET 5 Update (2020 and later)
Use LinkGenerator
as detailed in @Dmitry Pavlov's answer on this thread. It's injectable as part of the web framework, and works with the HttpContext
already available in controllers, or accessible in other services by injecting the IHttpContextAccessor
.
For ASP.NET Core RC2 there is an issue for this on the github repo. Instead of injecting the IUrlHelper
, take an IUrlHelperFactory
. It also sounds like you'd need the IActionContextAccessor
injected as a Controller
no longer has a public property ActionContext
.
Register the dependency:
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
Then depend on it:
public SomeService(IUrlHelperFactory urlHelperFactory,
IActionContextAccessor actionContextAccessor)
{
var urlHelper =
urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
}
Then use it as you see fit.
Solution 2
For ASP.NET Core 3.x app just inject IHttpContextAccessor
and LinkGenerator
to your controller or service. They should be already available in DI
.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace Coding-Machine.NET
{
public class MyService
{
private readonly IHttpContextAccessor _accessor;
private readonly LinkGenerator _generator;
public MyService(IHttpContextAccessor accessor, LinkGenerator generator)
{
_accessor = accessor;
_generator = generator;
}
private string GenerateConfirmEmailLink()
{
var callbackLink = _generator.GetUriByPage(_accessor.HttpContext,
page: "/Account/ConfirmEmail",
handler: null,
values: new {area = "Identity", userId = 123, code = "ASDF1234"});
return callbackLink;
}
}
}
If your app can't resolve IHttpContextAccessor
just add this to DI
:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
}
Solution 3
For Net Core 2.0
Add this after service.AddMvc()
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddScoped<IUrlHelper>(factory =>
{
var actionContext = factory.GetService<IActionContextAccessor>()
.ActionContext;
return new UrlHelper(actionContext);
});
Solution 4
For .Net Core 2.0
services.AddMvc();
services.AddScoped<IUrlHelper>(x =>
{
var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
var factory = x.GetRequiredService<IUrlHelperFactory>();
return factory.GetUrlHelper(actionContext);
});
Solution 5
ASP.NET Core 2.0
Install
PM> Install-Package AspNetCore.IServiceCollection.AddIUrlHelper
Use
public void ConfigureServices(IServiceCollection services)
{
...
services.AddUrlHelper();
...
}
Disclaimer: author of this package
RolandG
Updated on April 09, 2021Comments
-
RolandG about 3 years
In RC1,
IUrlHelper
could be injected in services (withservices.AddMvc()
in startup class)This doesn't work anymore in RC2. Does anybody know how to do it in RC2 as just newing up a
UrlHelper
requires anActionContext
object. Don't know how to get that outside a controller. -
caesay over 6 yearsDisclaimer: You are the author of this package
-
Phathutshedzo Khabubu almost 6 yearsI am trying to access IUrlHelper on a Hub in aspnet signalr core 2.1 will your package work?
-
tchelidze almost 6 years@PhathutshedzoKhabubu package just registers
IUrlHelper
inServiceCollection
with necessary dependencies. As far asDI
is available,IUrlHelper
will also be available. -
Phathutshedzo Khabubu almost 6 yearsI installed this package in an asp,net core 2.0.6 application and tried injecting the IUrlHelper in a singnalR Core Hub but it was not injected and got back null so thats way I raised that and note I added
services.AddUrlHelper();
afterservices.AddMvc()
-
tchelidze almost 6 years@PhathutshedzoKhabubu How are you accessing
IUrlHelper
? if you're injecting it into constructor and it's not available, then you'll get exception instead ofnull
-
Phathutshedzo Khabubu almost 6 yearsI tried via constructor injection than I got an exception but Via IUrlHelperFactory the action context is null therefore it throws an exception that the argument can not be null
-
Mohammed Noureldin almost 6 years@PhathutshedzoKhabubu, have you solved the issue? I have the same problem
-
tchelidze almost 6 years@MohammedNoureldin @PhathutshedzoKhabubu
IUrlHepler
is only available inside HttpContext. You can't access it outside, let's say in a background job, etc. -
David Pine almost 6 yearsI'm not sure what to say, perhaps there is a bug - otherwise there might be something in the github.com/aspnet/Announcements repo?
-
Stephen about 5 yearsThis doesn't answer the question. Often you don't want to take a dependency on a concrete controller in a class.
-
onefootswill about 5 yearsAgree with @Stephen . I want to inject the
IUrlHelper
into a Ui Service which has no dependency on a controller. I mean, why would it? -
Oleksandr Dudnyk about 5 yearsIf I'm not mistaken the behavior of IUrlHelper depends on current Route and RouteData. In the case of direct injecting into Ui Service you may end up with surprising results.
-
Mohammad Azhdari almost 5 years@OleksandrDudnyk you're absolutely right. I've faced this "surprising" result. Is there any alternative for IUrlHelper to use correctly in a class?
-
Bob.at.Indigo.Health over 4 yearsAdded this code to my
Startup.cs
, injected IUrlHelper into my tag helper class asurlHelper
. When I callurlHelper.Action()
it throwsIndexOutOfRangeException
. -
maxbeaudoin over 4 yearsWhat's your source on "you must not inject and IUrlHelper"?
-
user510101 about 3 yearsthough this is the accepted answer from 2016, as with most things in tech, things change with time. As of 2021, the better answer for ASP.NET Core 3+ and ASP.NET 5 is to use the
LinkGenerator
type as detailed in @Dmitry Pavlov's answer below. -
T-moty about 3 yearsThe only downside of this approach is that you lose every custom-made extension method on IUrlHelper. Sadly in that case you have to rely on
IUrlHelperFactory
-
Power Star about 2 yearsIf we have controller level route value, this method expects to add them instead prefill. Do you know anyway to prefill it.