0

I slipped into a deep problem with sessions in app (asp.net core mvc). This kind of problem was never occurred to me till i was in Asp.net mvc.

Sessions are working fine and every value of session is retained when I check values of session using breakpoint in visual studio. But if I remove breakpoint and just run my app, then session values gets empty/null and this issue is intermittent. I can consider this as a big flaw/bug in .net core mvc.

I have checked few answers in Session variable value is getting null in ASP.NET Core and Session Lost in Asp.net Core application but none of them are working for me.

I have these settings in startup.cs

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseSession();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                name: "areas",
                template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }


      services.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => false;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
     services.AddSession(options =>
                {
                    options.IdleTimeout = TimeSpan.FromDays(1);
                });

  services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            }).AddCookie("Cookies", options =>
            {
                // Configure the client application to use sliding sessions
                options.SlidingExpiration = true;
                // Expire the session of 15 minutes of inactivity
                options.ExpireTimeSpan = TimeSpan.FromDays(1);
                if (appSettings.RedisCachingEnabled)
                {
                    options.EventsType = typeof(CustomCookieAuthenticationEvents);
                }
                options.Cookie.HttpOnly = true;
            })

I am now stuck to give build for this project because initially the sessions worked fine. Finally I am setting and getting session like this

UserController.cs class

public IActionResult SetUsers(int id) {
 _sessionData.users= some api call that get users;
  return RedirectToAction("LoadUsers", "Home", new
                {
                    area = "Admin",
                 });
}

Admin area/ homeController.cs

 public IActionResult LoadUsers() {
       var users = _sessionData.users;  // some users are lost when trying to get users from session
       // some time its completely null. But if applied breakpoint, it shows correct session                        
 }

This is my session class

public class SessionData : ISessionData
    {
        public IHttpContextAccessor _httpContextAccessor;


        public SessionData(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public List<User> users
        {
            get
            {
                var users= _httpContextAccessor.HttpContext.Session.GetObjectFromJson<List<User>>("users");
                if (users == null)
                {
                    users = new List<User>();
                }
                return users;
            }

            set
            {
                _httpContextAccessor.HttpContext.Session.SetObjectAsJson("users", value);
            }
        }

}

1 Answer 1

0

You can create your own extension method for IHttpContextAccessor to save json data or retrieve it in a session. Here is an example

public static class Session
{
        private static IHttpContextAccessor _httpContextAccessor;
        private static ISession _session;

        public static void Initialized(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
            _session = _httpContextAccessor.HttpContext.Session;
        }
        public static bool SetObject(this IHttpContextAccessor httpContextAccessor, string key, object value)
        {
            bool status = false;
            try
            {
                Initialized(httpContextAccessor);
                _session.SetString(key, JsonConvert.SerializeObject(value));

                status = true;
            }
            catch (Exception ex)
            {

            }

            return status;

        }
        public static T GetObject<T>(this IHttpContextAccessor httpContextAccessor, string key)
        {
            try
            {
                Initialized(httpContextAccessor);
                var value = _session.GetString(key);
                return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
            }
            catch (Exception ex)
            {
                return default(T);
            }

        }
    
}

and in your controller, you inject an instance of IHttpContextAccessor in your constructor and you should be able to retrieve and save objects into a session

    public class SessionController : Controller
{
    private readonly UserInfo _user;

    public SessionController (IHttpContextAccessor iHttpContextAccessor)
    {
        _user = iHttpContextAccessor.GetObject<UserInfo>("user");//get session with 
                                  //key user 
    }


public IActionResult Login(LoginModel User)
    {
        
                        UserInfo userInfo = new UserInfo
                        {
                            Name = "name",
                            Id = 1
                        };
                        _iHttpContextAccessor.SetObject("user", userInfo);//set 
                                       //userinfo class into session
      }

User Info class:

 public class UserInfo
{

    public string Name{ get; set; }
    public int Id{ get; set; }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.