调用void方法后TempData数据丢失问题求助
TempData数据丢失问题:跨控制器实例传递失效的解决办法
你遇到的问题核心在于手动实例化UserInfoController的方式,导致两个控制器实例没有共享同一个HttpContext——而TempData是依赖当前请求的HttpContext存储的,所以在UserInfoController里存入的TempData,在主控制器Controller A中根本访问不到。
为什么你之前的尝试都无效?
- Session空引用:手动new的控制器没有绑定当前请求的HttpContext,自然无法访问Session对象
- ViewBag无效:ViewBag是控制器实例的专属属性,两个不同的控制器实例的ViewBag完全独立,数据无法互通
- TempData.Keep/Peek没用:这些方法是针对同一次请求内TempData的生命周期延长,但你的问题是数据根本没存入主控制器能访问的TempData容器里,所以起不到作用
最佳解决方案:重构方法,直接返回处理后的列表
最稳妥的方式是把reLabelLogs改成返回处理后的List<AttendanceLog>,完全跳过TempData这类请求级别的存储,直接在控制器间传递数据。
第一步:修改UserInfoController的方法
public List<AttendanceLog> reLabelLogs(DateTime? startDate, DateTime? startDateTime, int? empId, int? isPending, int? isManual, DateTime? manualDate , List<AttendanceLog> pList) { List<AttendanceLog> data; bool noSave = false; DateTime today = DateTime.Today; // 补充你原代码中用到的today变量 // 原有的逻辑代码 if (pList == null) { data = db.AttendanceLogs .Where(z => z.EmpID == empId && z.Date >= startDate && z.Date <= today).ToList(); } else { noSave = true; data = pList.ToList(); } foreach (var log in data) { // 你的业务处理代码 } // 直接返回处理后的列表,不用存TempData return data; }
第二步:在Controller A中直接接收返回值
public ActionResult Index(int? Page, int? id, int? attId, int? EnrollNumber, int? attend, DateTime? reqDate, DateTime? reqDT, DateTime? reqTime, DateTime? StartDate, string deets = " ", string preAppr = "", string type = "") { // some code // 实例化控制器(如果项目用了依赖注入,建议通过构造函数注入更规范) var userInfoController = new UserInfoController(); // 直接调用方法并接收返回的处理后的列表 var atLogs = userInfoController.reLabelLogs(reqTime.Value.Date, reqTime.Value, id, 0, 0, null, attLogs); return View(atLogs); }
备选方案:共享控制器上下文(不推荐,耦合性高)
如果你一定要用TempData传递,可以手动将主控制器的ControllerContext赋值给新实例化的UserInfoController,让它们共享同一个HttpContext:
public ActionResult Index(int? Page, int? id, int? attId, int? EnrollNumber, int? attend, DateTime? reqDate, DateTime? reqDT, DateTime? reqTime, DateTime? StartDate, string deets = " ", string preAppr = "", string type = "") { // some code var userInfoController = new UserInfoController(); // 关键:共享当前控制器的上下文 userInfoController.ControllerContext = this.ControllerContext; userInfoController.reLabelLogs(reqTime.Value.Date, reqTime.Value, id, 0, 0, null, attLogs); var atLogs = (List<AttendanceLog>)TempData["ppList"]; return View(atLogs); }
这种方式虽然能解决问题,但会让控制器间的耦合度变高,不如第一种直接返回数据的方式清晰。
内容的提问来源于stack exchange,提问作者user9570515
相关产品推荐
相关产品推荐

