Как использовать внедрение зависимостей в ASP.NET Core 2.0 для IHttpcontextAccessor - PullRequest
0 голосов
/ 07 мая 2018

Я хочу настроить службу для добавления текущего HttpContext в класс в моем проекте, чтобы он мог управлять файлами cookie.

Я настроил службу таким образом в моем Startup.cs классе:

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

Как использовать этот сервис в классе C #?

Моя попытка была такой:

Мой класс для управления куки, я хочу ввести текущий 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 голосов
/ 07 мая 2018

Есть несколько различных способов сделать это, когда вы хотите, чтобы класс мог использовать внедрение зависимостей, он должен быть зарегистрирован, однако я считаю, что все контроллеры должны автоматически регистрироваться в приложении 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);
    }
}
0 голосов
/ 07 мая 2018

Это, похоже, проблема XY .

На самом деле нет необходимости обращаться к 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");
}
0 голосов
/ 07 мая 2018

Попробуйте это:

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

Другим способом было бы зарегистрировать сам класс Cookie и затем внедрить его в конструктор.

...