0

ApplicationDBContext.cs

public DbSet<Register> RegisterAccount { get; set; }

Register Model

public class Register
{
    [Key]
    public int RegisterId { get; set; }
    [Required]
    [DataType(DataType.EmailAddress, ErrorMessage = "Please enter a valid e-mail address")]
    public string Email { get; set; }
    [Required]
    [Display(Name = "Full Name")]
    public string Name { get; set; }
    [Required]
    [DataType(DataType.Password)]
    [MinLength(5, ErrorMessage = "Password length cannot be less than 5")]
    public string Password { get; set; }

    [NotMapped] // Does not effect the database
    [Compare("Password")]
    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Confirm Password")]
    public string ConfirmPassword { get; set; }

}

I want to use session data in various controllers, how do I manage that?

LoginController.cs

public IActionResult Login(Login user)
{
        if (ModelState.IsValid)
        {
            var obj = _db.RegisterAccount.Where(u => u.Email.Equals(user.Email) && u.Password.Equals(user.Password)).FirstOrDefault();

            if (obj != null)
            {
                user.RegisterId = obj.RegisterId;
                _db.LoginAccount.Add(user);
                _db.SaveChanges();
                HttpContext.Session.SetObjectAsJson("Register", obj);
                return RedirectToAction("LoggedIn");
            }
        }

        ModelState.AddModelError("", "Some Error Occured");

        return RedirectToAction("Login");
}

public IActionResult LoggedIn()
{
        var userDetails = HttpContext.Session.GetObjectFromJson<Register>("Register");
        int? thisUserID = Convert.ToInt32(userDetails.RegisterId);

        if (thisUserID != null)
        {
            TempData["Users"] = userDetails;
            return View(); 
        }
        else
        {
            return RedirectToAction("Login");
        }
}

SessionExtension.cs

public static class SessionExtension
{
    public static void SetObjectAsJson(this ISession session, string key, object value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T GetObjectFromJson<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
    }
}

LoggedIn.cshtml View

@using Microsoft.AspNetCore.Http

@inject IHttpContextAccessor HttpContextAccessor


@{
    var userdetails = HttpContextAccessor.HttpContext.Session.GetObjectFromJson<Register>("Register"); // userdetails is available
}

<h1>Hi @userdetails.Name</h1>

Here, the username is displayed.

Say I have another controller Home and in the Index View I want to access the details of logged in user, how do I do it? I have tried

HomeController/Index.cshtml view

@using Microsoft.AspNetCore.Http

@inject IHttpContextAccessor HttpContextAccessor


@{
    var userdetails = HttpContextAccessor.HttpContext.Session.GetObjectFromJson<Register>("Register"); // userdetails remains null
}

<h1>Hi @userdetails.Name</h1>

Home Controller Index

 public IActionResult Index()
        {
           
            return View();
        }

What I want to do is to display the user name in my home controller index view as well as my login controller index view whenever the user has logged in.

Kaushik Ghosh
  • 27
  • 1
  • 1
  • 6
  • I am may be missing something obvious, but what is the TempData object here? I don't see it defined, but is this supposed to be tied to your session collection? – Ben Matthews Apr 04 '22 at 14:47
  • @BenMatthews I have added the Register Model and ApplicationDbContext for better understanding. – Kaushik Ghosh Apr 04 '22 at 15:04
  • Thank you for expanding, but I am not sure if this helps me understand what the TempData variable is or does. Is this supposed to just hold session data? I see you set your session information HttpContext.Session.SetObjectAsJson and then get it with HttpContext.Session.GetObjectFromJson which looks fine. I am just not sure what the TempData variable is. Are we sure the information is getting into TempData? What would happen if you used @HttpContext.Session.GetObjectFromJson("Register").Name instead of @user.Name in the view? – Ben Matthews Apr 04 '22 at 15:38
  • Shows Error CS120: An object reference is required for the nonstatic field, method, or property HttpContext.Session. Basically, I have to setObjectasJson which I have already defined in the controller. What I want to do Is to check whenever the user has logged in succesfully and display the user name in my home controller index view as well as my login controller index view. That's All. Now coming to why I am using tempdata, that is because to pass data from one controller to another , we have to use tempdata – Kaushik Ghosh Apr 04 '22 at 18:06
  • [TempData](https://stackoverflow.com/q/10487008/2030565) is temporary and will not persist beyond the next request. Use the `Session` store, cookies, or the browser's Web Storage API. – Jasen Apr 04 '22 at 19:06
  • Are you sure your LoggedIn.cshtml can work fine? By using your code it will get `InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type .... ` error. That is because `Session` uses `IDistributedCache`. `IDistributedCache` doesn't have the capability to accept objects or to serialize objects. If you just want use the name, I suggest you just store the name to Session. – Rena Apr 05 '22 at 02:31

1 Answers1

0

In order to show your Session on your View, you can inject IHttpContextAccessor implementation to your view and use it to get the Session object as required:

@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor HttpContextAccessor
@{
    //Get object from session
    var mySessionObject = HttpContextAccessor.HttpContext.Session.GetObjectFromJson<Register>("Register");
 }

<h1>@mySessionObject.Name</h1>
//So on

You do not need TempData for your case since you are already setting up your Session. TempData is used when you want to persist your variables from one Controller action to another to use them in the action method itself.

Now regarding your problem that the Session is not accessible in other Controller, you need to add services.AddDistributedMemoryCache() in order to have some place to store your Session data. You can read more on MSDN

In your Startup.cs, add the following:

public void ConfigureServices(IServiceCollection services)
{
  //Added for session state
  services.AddDistributedMemoryCache();

  services.AddSession(options =>
  {
     options.IdleTimeout = TimeSpan.FromMinutes(10);               
  });
}
Rahul Sharma
  • 7,768
  • 2
  • 28
  • 54
  • Shows Error CS0428: Cannot convert method group 'GetObjectFromJson' to non-delegate type 'object'. Did you intend to invoke the method? – Kaushik Ghosh Apr 04 '22 at 19:26
  • @KaushikGhosh I have updated my answer. Can you show what you are attempting to do? You can refer to this answer: https://stackoverflow.com/questions/43698878/how-to-get-session-value-asp-net-core-inside-a-view – Rahul Sharma Apr 04 '22 at 19:29
  • I have added an answer to show what I am attempting to do , it is working in LoginController/index view but in HomeController/Index userDetails variable remains null – Kaushik Ghosh Apr 04 '22 at 19:47
  • @KaushikGhosh Do not add an answer, rather update your question with your current scenario. Also are you setting your `Session` variable correctly? It could be that you might have not setup your `Session` before you are calling Index view on home ? – Rahul Sharma Apr 04 '22 at 19:50
  • I am sorry but this is my first time working on MVC, but do I need to set up session in Home controller again and if yes, then how? I have added the Home Controller Index view to my question for reference. – Kaushik Ghosh Apr 04 '22 at 20:01
  • @KaushikGhosh Updated my answer to include the information regarding your problem – Rahul Sharma Apr 05 '22 at 06:29
  • Rahul Sharma, Thank you so much!. That worked , Do I have to follow the same procedure for authorization of session ? For reference : https://stackoverflow.com/questions/71748831/how-to-authorize-a-session-in-mvc-net-core – Kaushik Ghosh Apr 05 '22 at 08:56