Подтвердить что ты не робот

Не удалось использовать UrlHelper

В настоящее время я пытаюсь сделать что-то, что было простым и простым в ASP.NET 4, но это не относится сейчас к ASP.NET 5.

Раньше использовать UrlHelper было просто:

var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);

Однако я не могу на всю жизнь обмануть голову тем, как использовать новый UrlHelper. Я смотрю на тестовые сценарии, и либо я совершенно небрежен, либо что-то упускаю, и я не могу понять, как это понять. Любая помощь здесь в расчистке этого будет замечательной.

4b9b3361

Ответ 1

Обновление - сообщение RC2

Как упоминалось в @deebo, вы больше не можете получить IUrlHelper непосредственно из DI. Вместо этого вам нужно ввести IUrlHelperFactory и IActionContextAccessor в свой класс и использовать их для получения экземпляра IUrlHelper, как в:

public MyClass(IUrlHelperFactory urlHelperFactory, IActionContextAccessor actionAccessor)
{
    this.urlHelperFactory = urlHelperFactory;
    this.actionAccessor = actionAccessor;
}

public void SomeMethod()
{
    var urlHelper = this.urlHelperFactory.GetUrlHelper(this.actionAccessor.ActionContext);
}

Вам также необходимо зарегистрировать в своем классе запуска (IUrlHelperFactory уже зарегистрирован по умолчанию):

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

Помните, что это будет работать только до тех пор, пока код, где вы получаете actionContext, запускается после промежуточного программного обеспечения MVC/routing! (В противном случае actionAccessor.ActionContext будет null)


Я получил IUrlHelper с помощью IServiceProvider в HttpContext.RequestServices.

Обычно у вас будет свойство HttpContext:

  • В методе действий контроллера вы можете:

    var urlHelper = this.Context.RequestServices.GetRequiredService<IUrlHelper>();
    ViewBag.Url = urlHelper.Action("Contact", "Home", new { foo = 1 });
    
  • В фильтре вы можете:

    public void OnActionExecuted(ActionExecutedContext context)
    {
        var urlHelper = context.HttpContext.RequestServices.GetRequiredService<IUrlHelper>();
        var actionUrl = urlHelper.Action("Contact", "Home", new { foo = 1 });
        //use actionUrl ...
    }
    

Другим вариантом будет использование встроенной инъекции зависимостей, например, у вашего контроллера может быть такой конструктор, как следующий, и во время выполнения будет предоставлен экземпляр IUrlHelper:

private IUrlHelper _urlHelper;
public HomeController(IUrlHelper urlHelper)
{
    _urlHelper = urlHelper;
}

Ответ 2

Думаю, что я поделился бы с будущим RC2, так как текущий ответ больше не будет работать.

От RC 2 вам нужно будет явно зарегистрировать IActionContextAccessor и IUrlHelperFactory

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddSingleton<IUrlHelperFactory, UrlHelperFactory>();

Затем используйте локатор DI/службы:

public EmailTagHelper(IUrlHelperFactory urlHelperFactory, IActionContextAccessor actionContextAccessor)
{
  _urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
}

Я писал об этом здесь в отношении TagHelpers: http://devonburriss.me/asp-net-5-tips-urlhelper

Ответ 3

Если вам нужен только метод UrlHelper.Link, как я, вам больше не нужен UrlHelper, просто используйте Url.Link

Ответ 4

В Startup.cs

   services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
   services.AddSingleton<IUrlHelperFactory, UrlHelperFactory>();
   services.AddScoped(it => it.GetService<IUrlHelperFactory>()
                    .GetUrlHelper(it.GetService<IActionContextAccessor>().ActionContext));

Альтернативно

PM> Install-Package AspNetCore.IServiceCollection.AddIUrlHelper 

В Startup.cs

services.AddUrlHelper();