无法使用UrlHelper

时间:2015-06-07 17:18:20

标签: asp.net asp.net-core-mvc

我目前正在尝试在ASP.NET 4中做一些简单而直接的事情,但现在在ASP.NET 5中就是这样。

以前使用UrlHelper很简单:

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

然而,我不能为我的生活包围如何使用新的UrlHelper。我正在查看测试用例,要么我完全愚蠢,要么我错过了一些东西,而我似乎无法弄明白。这里有任何帮助来清理这个都很棒。

5 个答案:

答案 0 :(得分:16)

更新 - 发布RC2

正如@deebo所说,你不再能直接从DI获得IUrlHelper。相反,您需要在类中注入IUrlHelperFactoryIActionContextAccessor并使用它们来获取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 /路由中间件之后运行时,这才会起作用! (否则actionAccessor.ActionContext将为空)

我使用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;
}

答案 1 :(得分:12)

以为我会分享即将到来的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

答案 2 :(得分: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();

答案 3 :(得分:2)

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

答案 4 :(得分:1)

没有构建特殊工厂类的短版本

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