Внедрение IUrlHelper в ASP.NET Core

В RC1 IUrlHelper можно было внедрить в службы (с services.AddMvc() в классе запуска)

Это больше не работает в RC2. Кто-нибудь знает, как это сделать в RC2, так как для того, чтобы просто обновить UrlHelper, требуется объект ActionContext. Не знаю, как получить это за пределами контроллера.


person RolandG    schedule 19.05.2016    source источник


Ответы (6)


.NET Core 3+ и .NET 5 Update (2020 г. и новее)

Используйте LinkGenerator, как описано в ответе на эту тему @Dmitry Pavlov. Он вводится как часть веб-инфраструктуры и работает с HttpContext, уже доступным в контроллерах или доступным в других службах путем внедрения IHttpContextAccessor.

Для ASP.NET Core RC2 существует проблема в репозитории github.. Вместо того, чтобы вводить IUrlHelper, возьмите IUrlHelperFactory. Также похоже, что вам понадобится внедренный IActionContextAccessor, поскольку Controller больше не имеет общедоступного свойства ActionContext.

Зарегистрируйте зависимость:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

Тогда полагайтесь на это:

public SomeService(IUrlHelperFactory urlHelperFactory,
                   IActionContextAccessor actionContextAccessor)
{
 
    var urlHelper =
        urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
}

Затем используйте его по своему усмотрению.

person David Pine    schedule 19.05.2016
comment
Я не уверен, что сказать, возможно, это ошибка - иначе может быть что-то в github.com/ aspnet / Объявления репо? - person David Pine; 18.06.2018
comment
хотя это общепринятый ответ с 2016 года, как и в большинстве случаев в сфере технологий, со временем все меняется. С 2021 года лучшим ответом для ASP.NET Core 3+ и ASP.NET 5 будет использование типа LinkGenerator, как подробно описано в ответе @Dmitry Pavlov ниже. - person Thiago Silva; 08.04.2021

Для приложения ASP.NET Core 3.x просто введите IHttpContextAccessor и _ 2_ к вашему контроллеру или службе. Они должны быть уже доступны в 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;
        }
    }
}

Если ваше приложение не может разрешить IHttpContextAccessor, просто добавьте это в DI:

public void ConfigureServices(IServiceCollection services)
{
     services.AddHttpContextAccessor();
}
person Dmitry Pavlov    schedule 17.01.2020
comment
Единственным недостатком этого подхода является то, что вы теряете все настраиваемые методы расширения в IUrlHelper. К сожалению, в этом случае вам придется полагаться на IUrlHelperFactory - person T-moty; 17.04.2021

Для Net Core 2.0

Добавьте это после service.AddMvc()

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddScoped<IUrlHelper>(factory =>
{
    var actionContext = factory.GetService<IActionContextAccessor>()
                                   .ActionContext;
    return new UrlHelper(actionContext);
});
person frostymarvelous    schedule 02.03.2018
comment
Добавил этот код в мой Startup.cs, внедрил IUrlHelper в мой вспомогательный класс тегов как urlHelper. Когда я звоню urlHelper.Action(), он бросает IndexOutOfRangeException. - person Bob.at.Indigo.Health; 23.08.2019

Для .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);
});
person Dilhan Jayathilake    schedule 14.07.2018

ASP.NET Core 2.0

Установить

PM> Install-Package AspNetCore.IServiceCollection.AddIUrlHelper

Использование

public void ConfigureServices(IServiceCollection services)
{
   ... 
   services.AddUrlHelper();
   ... 
}

Заявление об ограничении ответственности: автор этого пакета

person tchelidze    schedule 18.10.2017
comment
Отказ от ответственности: вы являетесь автором этого пакета - person caesay; 31.10.2017
comment
Я пытаюсь получить доступ к IUrlHelper на концентраторе в aspnet signalr core 2.1. Будет ли ваш пакет работать? - person Phathutshedzo Khabubu; 24.05.2018
comment
Пакет @PhathutshedzoKhabubu просто регистрирует IUrlHelper в ServiceCollection с необходимыми зависимостями. Насколько доступно DI, будет доступно и IUrlHelper. - person tchelidze; 25.05.2018
comment
Я установил этот пакет в приложение asp, net core 2.0.6 и попытался ввести IUrlHelper в SingnalR Core Hub, но он не был введен и получил значение null, поэтому я поднял его и заметил, что добавил services.AddUrlHelper(); после services.AddMvc() - person Phathutshedzo Khabubu; 25.05.2018
comment
@PhathutshedzoKhabubu Как вы получаете доступ к IUrlHelper? если вы вводите его в конструктор, а он недоступен, вы получите исключение вместо null - person tchelidze; 25.05.2018
comment
Я попробовал с помощью инъекции конструктора, чем получил исключение, но через IUrlHelperFactory контекст действия имеет значение null, поэтому он выдает исключение, что аргумент не может быть нулевым - person Phathutshedzo Khabubu; 25.05.2018
comment
@PhathutshedzoKhabubu, ты решил проблему? У меня точно такая же проблема - person Mohammed Noureldin; 18.06.2018
comment
@MohammedNoureldin @PhathutshedzoKhabubu IUrlHepler доступен только внутри HttpContext. Вы не можете получить к нему доступ снаружи, скажем, в фоновом режиме и т. Д. - person tchelidze; 18.06.2018

Для ASP.Net Core 2.0 не следует вводить IUrlHelper. Он доступен как свойство контроллера. ControllerBase.Url - это экземпляр IUrlHelper.

person Oleksandr Dudnyk    schedule 23.01.2019
comment
Это не отвечает на вопрос. Часто вы не хотите зависеть от конкретного контроллера в классе. - person Stephen; 18.04.2019
comment
Согласитесь с @Stephen. Я хочу ввести IUrlHelper в службу пользовательского интерфейса, которая не зависит от контроллера. Я имею в виду, с чего бы это? - person onefootswill; 23.04.2019
comment
Если я не ошибаюсь, поведение IUrlHelper зависит от текущего маршрута и RouteData. В случае прямого внедрения в службу пользовательского интерфейса вы можете получить удивительные результаты. - person Oleksandr Dudnyk; 01.05.2019
comment
@OleksandrDudnyk, ты абсолютно прав. Я столкнулся с этим удивительным результатом. Есть ли альтернатива для правильного использования IUrlHelper в классе? - person Mohammad Azhdari; 16.05.2019
comment
Какой у вас источник, вы не должны вводить и IUrlHelper? - person maxbeaudoin; 25.10.2019