MVC 6 IUrlHelper依赖注入

Gek*_*tek 11 c# dependency-injection inversion-of-control urlhelper asp.net-core-mvc

我想通过依赖注入使用IUrlHelper,以便能够使用其功能为不同的休息端点生成uris.我似乎无法弄清楚如何从头开始创建UrlHelper,因为它在MVC 6中发生了变化,而MVC并没有自动在IoC控制器中提供该服务.

设置是我的控制器接受api模型转换器类的内部模型,并使用IUrlHelper(通过Depenedency Injection).

如果有一个更好的替代IUrlHelper/UrlHelper,我可以用来为我的WebApi动作/控制器生成Uris,我愿意接受建议.

Lee*_*des 13

UrlHelper需要当前的操作上下文,我们可以从ActionContextAccessor获取它.我正在使用这个:

        services.AddScoped<IActionContextAccessor, ActionContextAccessor>();
        services.AddScoped<IUrlHelper>(x =>
        {
            var  actionContext = x.GetService<IActionContextAccessor>().ActionContext;
            return new UrlHelper(actionContext);
        });
Run Code Online (Sandbox Code Playgroud)

现在,您可以将IUrlHelper直接注入到需要它的任何内容中,而无需跳过IHttpContextAccessor.


Gek*_*tek 7

此方法现已过时.请看下面的更新.

而不是services.AddTransient<IUrlHelper, UrlHelper>()或试图直接注入IUrlHelper,您可以注入IHttpContextAccessor并从那里获取服务.

public ClassConstructor(IHttpContextAccessor contextAccessor)
{
    this.urlHelper = contextAccessor.HttpContext.RequestServices.GetRequiredService<IUrlHelper>();
}
Run Code Online (Sandbox Code Playgroud)

除非它只是一个bug,否则使用UrlHelper添加IUrlHelper服务不起作用.

更新2017-08-28

以前的方法似乎不再起作用.以下是一个新的解决方案.

将IActionContextAccessor配置为服务:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddSingleton<IActionContextAccessor, ActionContextAccessor>()
        .AddMvc();
}
Run Code Online (Sandbox Code Playgroud)

然后注入IActionContextAccessor和IUrlHelperFactory然后生成IUrlHelper,如下所示

public class MainController : Controller
{
    private IUrlHelperFactory urlHelperFactory { get; }
    private IActionContextAccessor accessor { get; }
    public MainController(IUrlHelperFactory urlHelper, IActionContextAccessor accessor)
    {
        this.urlHelperFactory = urlHelper;
        this.accessor = accessor;
    }

    [HttpGet]
    public IActionResult Index()
    {
        ActionContext context = this.accessor.ActionContext;
        IUrlHelper urlHelper = this.urlHelperFactory.GetUrlHelper(context);
        //Use urlHelper here
        return this.Ok();
    }
}
Run Code Online (Sandbox Code Playgroud)