2015-06-07 13 views
13

Obecnie próbuję zrobić coś, co było martwe proste i prosto do przodu w ASP.NET 4 to jednak ins't sprawę teraz w ASP.NET 5.Nie można wykorzystać UrlHelper

Wcześniej użyć UrlHelper to było proste:

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

Jednak nie mogę na całe życie obrócić głowę, jak korzystać z nowego UrlHelpera. Patrzę na przypadki testowe i albo jestem kompletnie głupia albo coś mi brakuje i nie mogę tego zrozumieć. Każda pomoc w oczyszczeniu tego będzie świetna.

Odpowiedz

15

Update - post RC2

Jak @deebo wspomniano, już nie mogą otrzymać IUrlHelper bezpośrednio z DI. Zamiast tego trzeba wstrzykiwania IUrlHelperFactory oraz IActionContextAccessor do swojej klasy i używać ich, aby uzyskać instancję IUrlHelper jak w:

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

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

Trzeba także zarejestrować w swojej klasie startowej (IUrlHelperFactory jest już zarejestrowany domyślnie):

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); 

Pamiętaj, to będzie działać tylko tak długo, jak kod gdzie masz actionContext działa po/routingu middleware MVC! (W przeciwnym razie actionAccessor.ActionContext byłby zerowy)


I pobraniu IUrlHelper pomocą IServiceProvider w HttpContext.RequestServices.

Zwykle trzeba będzie właściwość HttpContext pod ręką:

  • w sposobie działania kontrolera można zrobić:

    var urlHelper = this.Context.RequestServices.GetRequiredService<IUrlHelper>(); 
    ViewBag.Url = urlHelper.Action("Contact", "Home", new { foo = 1 }); 
    
  • w filtrze można zrobić:

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

Innym rozwiązaniem mogłoby być wykorzystanie wbudowanego wstrzykiwania zależności, na przykład kontroler może mieć konstruktor jak poniżej jednej i w czasie wykonywania instancji IUrlHelper będą dostarczone:

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

* facepalm * Nie wiedziałem, że mogę dostać pomocnika url poprzez dependancy iniekcji, jak byłem pod wrażeniem, że ten było coś, co należało dodać do usług. – Marqueone

2

Jeśli tylko potrzebują UrlHelper.Link Tak jak zrobiłem, nie potrzebujesz już UrlHelper, po prostu użyj Url.Link

11

Myślałem, że podzielę się tym z nadchodzącym RC2, ponieważ obecna odpowiedź przestanie działać.

Od RC 2 trzeba będzie wyraźnie zarejestrować IActionContextAccessor i IUrlHelperFactory

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

Następnie za pomocą lokalizatora DI/usług:

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

I napisał o tym tutaj w odniesieniu do TagHelpers: http://devonburriss.me/asp-net-5-tips-urlhelper

+0

Oprócz rejestracji IUrlHelper w konfiguracji startowej, o której wspomniałeś, nie jestem pewien, czy rozumiem, dlaczego i jak jest teraz inny niż oryginalne rozwiązanie? Lepsze pytanie brzmi: dlaczego muszę go najpierw zarejestrować? Wydaje się, że teraz jest dużo więcej pracy. – Marqueone

+0

Jedyna różnica polega na tym, że powinna działać w RC2. Aktualna odpowiedź jest obecnie poprawna. Rozmawiałem z RC2 i wpadłem na problem opisany w blogu połączonym z postem. Wspomniano również, że ten link git commit https://github.com/aspnet/Mvc/commit/9fc3a800562c866850d7c795cf24db7fa0354af6 wydaje się wskazywać na decyzję o projekcie, która ma na celu usunięcie zależności od IActionContextAccessor. Może @davidfowl lub ktoś inny z zespołu Aspnet może wyjaśnić –

2

W Startup.cs

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

Alternatywnie

PM> Install-Package AspNetCore.IServiceCollection.AddIUrlHelper 

W Startup.cs

services.AddUrlHelper(); 
Powiązane problemy