如何在ASP.NET Core 2.0中为IHttpcontextAccessor使用依赖注入

时间:2018-05-07 12:20:35

标签: c# asp.net-core dependency-injection asp.net-core-2.0

我想设置一个服务,在项目中的类中注入当前HttpContext,以便它可以管理cookie。

我在 Startup.cs 类中设置了这样的服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
    services.AddMvc();
}

如何在C#类中使用此服务?

我的尝试是这样的:

我的班级操纵cookie,我想注入当前的HttpContext

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Session;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace grupoveiculos.Infraestrutura.Session
{
    public class Cookie
    {
        private readonly IHttpContextAccessor _accessor;

        public Cookie(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        public void Set(string chave, string valor, int? dataExpiracao)
        {
            CookieOptions option = new CookieOptions();

            if (dataExpiracao.HasValue)
                option.Expires = DateTime.Now.AddMinutes(dataExpiracao.Value);
            else
                option.Expires = DateTime.Now.AddMilliseconds(10);

            _accessor.HttpContext.Response.Cookies.Append(chave, valor, option);
        }
    }
}

但是当我尝试在控制器中实例化我的Cookie类时,它说“没有与所需的形式参数访问器相对应的参数”。错误是非常合乎逻辑的,它期望构造函数参数。但我希望注入IHttpContextAccessor而不是我必须提供参数。

在我的控制器中,我试过了:

[HttpGet]
[Route("SelecionarIdioma")]
public IActionResult SelecionarIdioma(string cultura)
{
    Cookie cookie = new Cookie(); // expecting the accessor parameter
    cookie.Set("idioma", cultura, 60);

    return RedirectToAction("Index", "Grupo");
}

3 个答案:

答案 0 :(得分:3)

这似乎是XY problem

当您已经在控制器操作中访问响应时,实际上无需访问IHttpContextAccessor

您可以创建扩展方法来简化操作

public static void AddCookie(this HttpResponse response, string chave, string valor, int? dataExpiracao) {
    CookieOptions option = new CookieOptions();

    if (dataExpiracao.HasValue)
        option.Expires = DateTime.Now.AddMinutes(dataExpiracao.Value);
    else
        option.Expires = DateTime.Now.AddMilliseconds(10);

    response.Cookies.Append(chave, valor, option);
}

并从控制器操作中调用它。

[HttpGet]
[Route("SelecionarIdioma")]
public IActionResult SelecionarIdioma(string cultura) {
    Response.AddCookie("idioma", cultura, 60); //<-- extension method.    
    return RedirectToAction("Index", "Grupo");
}

答案 1 :(得分:1)

有几种不同的方法可以做到这一点,当你希望一个类能够使用依赖注入时,它需要注册,但我相信所有的控制器都应该在MVC应用程序中自动注册。

尝试直接将其注入控制器而不是Cookie。

public class MyController : Controller 
{
    private IHttpContextAccessor _accessor;

    public MyController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

    [HttpGet]
    [Route("SelecionarIdioma")]
    public IActionResult SelecionarIdioma(string cultura)
    {
        Cookie cookie = new Cookie(_accessor);
    }
}

答案 2 :(得分:-1)

试试这个:

var cookie = new Cookie(this.HttpContext.RequestServices.GetService<IHttpContextAccessor>());

另一种方法是注册Cookie类本身,然后将其注入构造函数。