RolandG
RolandG

Reputation: 1329

Injection of IUrlHelper in ASP.NET Core

In RC1, IUrlHelper could be injected in services (with services.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 an ActionContext object. Don't know how to get that outside a controller.

Upvotes: 66

Views: 36904

Answers (6)

David Pine
David Pine

Reputation: 24535

.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.

Upvotes: 88

Dmitry Pavlov
Dmitry Pavlov

Reputation: 28310

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();
}

Upvotes: 78

Oleksandr Dudnyk
Oleksandr Dudnyk

Reputation: 111

For ASP.Net Core 2.0 you must not inject an IUrlHelper. It’s available as a property of the controller. ControllerBase.Url is an IUrlHelper instance.

Upvotes: 0

frostymarvelous
frostymarvelous

Reputation: 2805

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);
});

Upvotes: 26

Dilhan Jayathilake
Dilhan Jayathilake

Reputation: 1890

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);
});

Upvotes: 5

tchelidze
tchelidze

Reputation: 8318

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

Upvotes: 3

Related Questions