You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

控制器间传递数据除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 00:45:53