Reputation: 353
I want to set up a service to inject the current HttpContext
in a class in my project so it can manage cookies.
I set up the service like this in my Startup.cs class:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddMvc();
}
How do I use this service in a C# class?
My attempt was like this:
My class to manipulate cookies, I want to inject the current 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". 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.
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");
}
Upvotes: 1
Views: 1870
Reputation: 247088
This appears to be an XY problem.
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
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");
}
Upvotes: 4
Reputation: 2889
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.
Try injecting it into the controller instead of the Cookie directly.
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);
}
}
Upvotes: 1
Reputation: 14535
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.
Upvotes: -1