无法使用 UrlHelper

Unable to utilize UrlHelper

我目前正在尝试做一些在 ASP.NET 4 中非常简单直接的事情,但是在 ASP.NET 5 中现在不是这种情况。

以前使用 UrlHelper 非常简单:

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

但是我终生无法思考如何使用新的 UrlHelper。我正在查看测试用例,要么我完全愚蠢,要么我遗漏了一些东西,但我似乎无法弄清楚。如果能帮助解决这个问题,那就太好了。

更新 - Post RC2

如@deebo 所述,您无法再直接从 DI 获得 IUrlHelper。相反,您需要将 IUrlHelperFactoryIActionContextAccessor 注入 class 并使用它们来获取 IUrlHelper 实例,如:

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

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

您还需要在您的启动程序中注册 class(IUrlHelperFactory 已默认注册):

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

请记住,只有当您获取 actionContext 的代码是 MVC/routing 中间件之后的 运行 时,这才会有效! (否则 actionAccessor.ActionContext 将为空)


我使用 HttpContext.RequestServices 中的 IServiceProvider 检索到了 IUrlHelper

通常你手边会有一个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;
}

如果你像我一样只需要 UrlHelper.Link 方法,你甚至不需要 UrlHelper 了,只需使用 Url.Link

我想我会分享即将到来的 RC2,因为当前的答案将不再有效。

从 RC 2 开始,您将需要显式注册 IActionContextAccessorIUrlHelperFactory

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

然后使用 DI/service 定位器:

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

我在这里写了关于 TagHelpers 的博客:http://devonburriss.me/asp-net-5-tips-urlhelper

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

没有建造特殊工厂的较短版本class

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
            .AddScoped<IUrlHelper>(sp => new UrlHelper(sp.GetRequiredService<IActionContextAccessor>().ActionContext));