【问题标题】:Why my session values are lost sometimes in .net core mvc application?为什么我的会话值有时会在 .net core mvc 应用程序中丢失?
【发布时间】:2020-09-04 14:55:53
【问题描述】:

我在应用程序 (asp.net core mvc) 中遇到了一个严重的会话问题。在我使用 Asp.net mvc 之前,我从来没有遇到过这种问题。

会话工作正常,当我在 Visual Studio 中使用断点检查会话值时,会保留会话的每个值。但是,如果我删除断点并仅运行我的应用程序,那么会话值将变为空/null,并且此问题是间歇性的。我可以认为这是 .net core mvc 中的一个大缺陷/错误。

我在Session variable value is getting null in ASP.NET CoreSession Lost in Asp.net Core application 中检查了几个答案,但没有一个对我有用。

我在 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;
            })

我现在坚持为这个项目提供构建,因为最初会话运行良好。最后我正在设置和获取这样的会话

UserController.cs 类

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

管理区/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                        
 }

这是我的课程

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);
            }
        }

}

【问题讨论】:

    标签: asp.net-core .net-core asp.net-core-mvc


    【解决方案1】:

    您可以为 IHttpContextAccessor 创建自己的扩展方法来保存 json 数据或在会话中检索它。 这是一个例子

    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);
                }
    
            }
        
    }
    

    在您的控制器中,您在构造函数中注入一个 IHttpContextAccessor 实例,您应该能够检索对象并将其保存到会话中

        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
          }
    

    用户信息类:

     public class UserInfo
    {
    
        public string Name{ get; set; }
        public int Id{ get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 2013-08-03
      相关资源
      最近更新 更多