简体   繁体   English

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

[英]How to use dependency injection in ASP.NET Core 2.0 for IHttpcontextAccessor

I want to set up a service to inject the current HttpContext in a class in my project so it can manage cookies. 我想设置一个服务,将当前的HttpContext注入项目中的类中,以便它可以管理cookie。

I set up the service like this in my Startup.cs class: 我在Startup.cs类中设置了以下服务:

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

How do I use this service in a C# class? 如何在C#类中使用此服务?

My attempt was like this: 我的尝试是这样的:

My class to manipulate cookies, I want to inject the current HttpContext . 我的类要操作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);
        }
    }
}

But when I try to instantiate my Cookie class inside the controller, it says that "there's no argument that corresponds to the required formal parameter accessor". 但是,当我尝试在控制器内部实例化Cookie类时,它表示“没有对应于所需形式参数访问器的参数”。 The error is very logical, it is expecting the constructor parameter. 该错误非常合乎逻辑,需要构造函数参数。 But I expected IHttpContextAccessor being injected instead of me having to provide a parameter. 但是我希望注入IHttpContextAccessor而不是必须提供参数。

In my controller I tried: 在我的控制器中,我尝试:

[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");
}

This appears to be an XY problem . 这似乎是一个XY问题

There is really no need to access the IHttpContextAccessor just to access the response when you already have access to it within the controller action 当您已经可以在控制器操作中访问响应时,实际上不需要访问IHttpContextAccessor即可访问响应

You can create an extension method to simplify things 您可以创建扩展方法来简化操作

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

and call it from the controller action. 并从控制器操作中调用它。

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

There are a few different ways to do this, when you want a class to be able to use dependency injection it needs to be registered, however I believe all the controllers should be registered automatically in an MVC app. 有几种不同的方法可以执行此操作,当您希望某个类能够使用依赖项注入时,需要对其进行注册,但是我相信所有控制器都应该在MVC应用程序中自动注册。

Try injecting it into the controller instead of the Cookie directly. 尝试将其注入控制器,而不是直接注入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);
    }
}

Try this: 尝试这个:

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

Another way would be to register the Cookie class itself and then inject it on the constructor. 另一种方法是注册Cookie类本身,然后将其注入构造函数中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM