Razor Pages登录后UserInfo为空,仅传UserId获取用户信息方法
问题根源说明
ASP.NET Core的每一次HTTP请求都是完全隔离的,内存中的类实例不会在请求之间共享:
- 你在登录页
OnPost方法中给UserInfo类赋值的所有属性,仅存在于「登录提交」这一次请求的内存空间里 - 执行
RedirectToPage跳转后,浏览器发起的是对/index的全新请求,之前的UserInfo实例已经被销毁 - 此时只有你显式写在路由参数里的
UserId,会被新请求的模型绑定机制识别,其他未通过持久化存储的属性自然全空
分步实现方案
1. 持久化存储UserId,无需跨页面手动传参
不要靠内存类实例存登录状态,跨请求可读取的持久化存储可以选两种,新手优先从易上手的Session方案开始:
- 首先在项目的
Program.cs中添加Session相关配置:// 注册Session服务 builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); // 登录状态有效期 options.Cookie.HttpOnly = true; }); // 配置请求管道启用Session app.UseSession(); - 修改登录页
OnPost的登录成功逻辑,把UserId存进Session,不再依赖路由参数传值:if (reader[2].ToString() == Userpassword) { var currentUserId = int.Parse(reader[0].ToString()); // 将UserId写入Session,后续所有页面都能直接读取 HttpContext.Session.SetInt32("CurrentUserId", currentUserId); // 跳转时不需要再附带UserId路由参数 return RedirectToPage("/index"); }
重要提醒:所有数据库查询必须改用参数化查询,禁止直接拼接用户输入的字符串,否则会有严重的SQL注入风险。你当前的登录查询语句可以修改为:
sqlcom = new SqlCommand("select * from users where userusername=@UserName", sqlcon); sqlcom.Parameters.AddWithValue("@UserName", Userinfo.Username);
2. 通过UserId查询完整用户信息
不管在哪个页面,只要从Session中读取到存储的UserId,直接查数据库就能拿到全部用户字段,不需要依赖之前请求的类实例值:
- 修改主页的
OnGet逻辑,读取Session中的UserId,补全用户信息给视图:public void OnGet() { // 从Session读取存储的UserId var currentUserId = HttpContext.Session.GetInt32("CurrentUserId"); if (currentUserId == null) { // 未登录状态直接给视图赋值空状态 Model.UserId = null; return; } // 根据UserId查库拿完整用户信息 sqlcon.Open(); var sqlcom = new SqlCommand("select * from users where userid=@UserId", sqlcon); sqlcom.Parameters.AddWithValue("@UserId", currentUserId); SqlDataReader reader = sqlcom.ExecuteReader(); if (reader.Read()) { Model.UserId = currentUserId; Model.UserName = reader[3].ToString(); // 把查到的用户名赋值给视图模型 } sqlcon.Close(); } - 这样视图里的欢迎逻辑就能正常读到用户名了,不需要额外传参。
正式项目的优化建议
如果是正式上线的项目,建议直接使用ASP.NET Core内置的Cookie身份认证机制,替代手动管理的Session:
- 登录成功后通过加密Cookie存储UserId,比Session更安全
- 所有页面可以直接从
HttpContext.User中读取用户ID,不需要手动写Session读写逻辑 - 内置的认证机制自带过期校验、防篡改能力,不需要自己维护状态逻辑
内容的提问来源于stack exchange,提问作者aaarianme
相关产品推荐
相关产品推荐

