无法使用 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
。相反,您需要将 IUrlHelperFactory
和 IActionContextAccessor
注入 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 开始,您将需要显式注册 IActionContextAccessor 和 IUrlHelperFactory
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));
我目前正在尝试做一些在 ASP.NET 4 中非常简单直接的事情,但是在 ASP.NET 5 中现在不是这种情况。
以前使用 UrlHelper 非常简单:
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
但是我终生无法思考如何使用新的 UrlHelper。我正在查看测试用例,要么我完全愚蠢,要么我遗漏了一些东西,但我似乎无法弄清楚。如果能帮助解决这个问题,那就太好了。
更新 - Post RC2
如@deebo 所述,您无法再直接从 DI 获得 IUrlHelper
。相反,您需要将 IUrlHelperFactory
和 IActionContextAccessor
注入 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 开始,您将需要显式注册 IActionContextAccessor 和 IUrlHelperFactory
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));