I have a class with a parameterless constructor and I am wondering how to get a value from the session. I have tried dependency injection but since I am using this class for deserialization, the httpcontextaccessor is always null.
public class Category
{
public Category()
{
_language = "french"; <-- how to get value from session
}
private string _Name;
public string Name {
get {
if (!string.IsNullOrEmpty(_language))
{
var dict = new Dictionary<string, string>();
this.localization.FirstOrDefault(x => x.TryGetValue(_language, out dict));
return dict != null && dict.ContainsKey("name") ? dict["name"] : _Name;
}
else
return _Name;
}
set
{
_Name = value;
}
}
public List<Dictionary<string, Dictionary<string, string>>> localization { get; set; }
}
CodePudding user response:
You can get session value in custom model like below:
public class Category
{
private readonly ISession _session; //add this..
public Category(ISession session)
{
_session = session;
_language = _session.GetString("language");
}
private string? _language;
private string _Name;
public string Name {
get {
if (!string.IsNullOrEmpty(_language))
{
var dict = new Dictionary<string, string>();
this.localization.FirstOrDefault(x => x.TryGetValue(_language, out dict));
return dict != null && dict.ContainsKey("name") ? dict["name"] : _Name;
}
else
return _Name;
}
set
{
_Name = value;
}
}
public List<Dictionary<string, Dictionary<string, string>>> localization { get; set; }
}
Test it in Controller:
public IActionResult Index()
{
HttpContext.Session.SetString("language", "en-US");
var model = new CategoryModel(HttpContext.Session);
return View();
}
Be sure add AddSession
and UseSession
middleware in Program.cs or in Startup.cs.
Reference: Configure session state
but since I am using this class for deserialization, the httpcontextaccessor is always null.
A simple demo you could follow:
Model:
public class CategoryModel
{
private readonly IHttpContextAccessor _contextAccessor;
public CategoryModel(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
_language = contextAccessor.HttpContext.Session.GetString("language");
}
//........
}
Test in Controller:
public class HomeController : Controller
{
private readonly IHttpContextAccessor _contextAccessor;
public HomeController(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public IActionResult Index()
{
HttpContext.Session.SetString("language", "en-US");
var model = new CategoryModel(_contextAccessor);
return View();
}
}
Register the service like:
//.....
builder.Services.AddSession();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
CodePudding user response:
So I created a static class:
public static class AppContext
{
public static IHttpContextAccessor HttpContextAccessor { get; set; }
public static void Configure(IHttpContextAccessor accessor)
{
HttpContextAccessor = accessor;
}
}
And then in the class where I couldn't do dependency injection, I was able to get the session:
public Category()
{
_language = AppContext.HttpContextAccessor.HttpContext.Session.GetString("language");
}
Had to add this to Configure in Startup:
AppContext.Configure(context);