Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 707
RolandG Avatar asked May 19 '16 11:05

RolandG


2 Answers

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

like image 60
David Pine Avatar answered Nov 20 '22 14:11

David Pine


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();
}
like image 69
Dmitry Pavlov Avatar answered Nov 20 '22 15:11

Dmitry Pavlov