控制器间传递数据除TempData外还有哪些方案?如何避免刷新丢失?
问题与解决方案
问题场景
当前使用TempData在控制器间传递UserID等数据,但用户执行强制刷新(Ctrl+Shift+R)后,TempData中的数据会丢失,导致后续逻辑出错。相关代码示例如下:
登录控制器代码
public ActionResult Index(Table_User user) { var user1 = repo.Find(x => x.UserMail == user.UserMail); if (user1 != null) { if (SecurityAlgorithms.CheckMD5Hash(user.UserPassword, user1.UserPassword)) { FormsAuthentication.SetAuthCookie(user1.UserName, false); Session["user1"] = user.UserName; var id = user.UserID; User userinfo = new User() { userID = id }; TempData["UserData"] = userinfo; return RedirectToAction("Index", "Home", new { area = "" }); } else { ViewBag.ErrorMessage = "Check your password!"; return View("Index", user); } } }
Home控制器代码
public ActionResult Index() { User userdata = TempData["UserData"] as User; if (userdata == null) { ViewBag.ErrorMessage = "error"; TempData["Message"] = "Error occurred: "; return View(); } else { var values = db.Table_RentedBooks.Where(a => a.UserID == userdata.UserID).ToList(); return View(values); } }
解决TempData丢失的办法
TempData默认仅保留到下一次请求,强制刷新会触发新请求,导致数据被清除。可通过以下方式延长其生命周期:
1. 使用Keep()或Peek()方法
读取TempData后调用Keep(),可保留数据供后续请求使用:
public ActionResult Index() { User userdata = TempData["UserData"] as User; if (userdata != null) { // 保留TempData数据,防止刷新丢失 TempData.Keep("UserData"); var values = db.Table_RentedBooks.Where(a => a.UserID == userdata.UserID).ToList(); return View(values); } else { ViewBag.ErrorMessage = "error"; TempData["Message"] = "Error occurred: "; return View(); } }
或使用Peek()读取数据但不标记为删除:
User userdata = TempData.Peek("UserData") as User;
2. 配置TempData使用Session存储
在Global.asax的Application_Start方法中设置TempData提供器为Session,数据会存储在Session中,直到Session超时或手动清除:
protected void Application_Start() { // 其他初始化配置 TempDataProvider = new SessionStateTempDataProvider(); }
更可靠的替代数据传递方案
1. 使用Session存储用户信息
Session是跨请求持久化的,只要Session未超时,刷新页面数据不会丢失:
修改登录控制器:
public ActionResult Index(Table_User user) { var user1 = repo.Find(x => x.UserMail == user.UserMail); if (user1 != null) { if (SecurityAlgorithms.CheckMD5Hash(user.UserPassword, user1.UserPassword)) { FormsAuthentication.SetAuthCookie(user1.UserName, false); // 将用户核心信息存入Session Session["UserID"] = user1.UserID; Session["UserName"] = user1.UserName; return RedirectToAction("Index", "Home", new { area = "" }); } else { ViewBag.ErrorMessage = "Check your password!"; return View("Index", user); } } }
修改Home控制器:
public ActionResult Index() { if (Session["UserID"] == null) { ViewBag.ErrorMessage = "error"; return View(); } int userId = (int)Session["UserID"]; var values = db.Table_RentedBooks.Where(a => a.UserID == userId).ToList(); return View(values); }
2. 从FormsAuthentication票据中获取用户ID
设置AuthCookie时,将UserID存入票据的UserData字段,后续从票据解析获取:
修改登录控制器:
public ActionResult Index(Table_User user) { var user1 = repo.Find(x => x.UserMail == user.UserMail); if (user1 != null) { if (SecurityAlgorithms.CheckMD5Hash(user.UserPassword, user1.UserPassword)) { // 创建包含UserID的认证票据 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, user1.UserName, DateTime.Now, DateTime.Now.AddMinutes(30), false, user1.UserID.ToString() // 存入UserID ); string encryptedTicket = FormsAuthentication.Encrypt(ticket); HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); Response.Cookies.Add(authCookie); return RedirectToAction("Index", "Home", new { area = "" }); } else { ViewBag.ErrorMessage = "Check your password!"; return View("Index", user); } } }
修改Home控制器:
public ActionResult Index() { if (!User.Identity.IsAuthenticated) { ViewBag.ErrorMessage = "error"; return View(); } // 解析票据获取UserID FormsIdentity identity = (FormsIdentity)User.Identity; FormsAuthenticationTicket ticket = identity.Ticket; int userId = int.Parse(ticket.UserData); var values = db.Table_RentedBooks.Where(a => a.UserID == userId).ToList(); return View(values); }
3. 根据登录用户名从数据库查询
利用已验证的登录身份,直接从数据库根据用户名查询用户信息,无需额外传递:
修改Home控制器:
public ActionResult Index() { if (!User.Identity.IsAuthenticated) { ViewBag.ErrorMessage = "error"; return View(); } // 根据当前登录用户名查询用户详情 var user1 = repo.Find(x => x.UserName == User.Identity.Name); if (user1 == null) { ViewBag.ErrorMessage = "error"; return View(); } var values = db.Table_RentedBooks.Where(a => a.UserID == user1.UserID).ToList(); return View(values); }
内容的提问来源于stack exchange,提问作者user17847724
相关产品推荐
相关产品推荐

