何时在ASP.Net MVC中使用TempData vs Session
我试图得到MVC框架的悬念,所以忍受着我。
现在,我正在使用会话存储的唯一事情是存储当前login的用户。 我的网站很简单。 对于这个例子,考虑三个域对象,人,会议和文件。 用户可以login并查看会议的“仅成员”configuration文件,并可以向其中添加文件,或查看会议的公开“configuration文件”(如果未login)。
所以,从会议的私人档案中,login的用户,我有一个“添加文件”链接。 此链接路由到FileContoller.Add(int meetingId)。 从这个动作中,我得到了用户想要使用会议ID添加文件的会议,但是在表单发布之后,我仍然需要知道用户正在向哪个会议添加文件。 这就是我的问题所在,我应该通过TempData传递“正在交互”会议,还是将其添加到Session存储?
这是我目前如何添加操作设置,但它不工作:
public ActionResult Add(int meetingId) { try { var meeting = _meetingsRepository.GetById(meetingId); ViewData.Model = meeting; TempData[TempDataKeys.CurrentMeeting] = meeting; /* add to tempdata here */ } catch (Exception) { TempData[TempDataKeys.ErrorMessage] = "Unable to add files to this meeting."; return RedirectToRoute("MeetingsIndex"); } return View(); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult Add(FormCollection form) { var member = Session[SessionStateKeys.Member] as Member; var meeting = TempData[TempDataKeys.CurrentMeeting] as Meeting; /* meeting ends up null here */ if (member == null) { TempData[TempDataKeys.ErrorMessage] = "You must be logged in to add files to an meeting."; return RedirectToRoute("LoginPage"); } if (meeting == null) { TempData[TempDataKeys.ErrorMessage] = "An error occurred. No meeting selected."; return RedirectToRoute("MeetingsIndex"); } // add files to meeting TempData[TempDataKeys.Notification] = "Successfully added."; return RedirectToRoute("AddFiles", new {meetingId = meeting.MeetingId}); }
编辑:
基于大多数的答案,任何人都可以提供什么样的数据(消息除外)应该存储在TempData vs Session中的任何示例?
TempData是会话,所以它们并没有完全不同。 但是,区别很容易理解,因为TempData仅用于redirect,并且仅用于redirect 。 因此,当您在TempData中设置一些消息,然后redirect时,您正确使用TempData。
但是,使用Session来处理任何types的安全性是非常危险的。 会话和成员完全独立于ASP.NET。 你可以从其他用户那里“窃取”会话 ,是的,人们这样攻击网站。 因此,如果您想要根据用户是否login来select性地停止发布信息,请查看IsAuthenticated ,如果要根据用户login的typesselect性地显示信息,请使用angular色提供程序 。 因为GET可以被caching,所以select性地允许访问GET中的动作的唯一方法是使用AuthorizeAttribute。
更新为了回应你所编辑的问题:你已经有了一个在你的问题中使用TempData的好例子,即在POST失败后返回一个简单的错误消息。 对于应该存储在Session中的内容(超出“不多”),我只是将Session视为特定于用户的caching。 像非用户特定的caching一样,您不应该将安全敏感信息放在那里。 但是,这是一个很好的地方,坚持看起来相对昂贵的东西。 例如,我们的Site.Master显示了用户的全名。 这存储在一个数据库中,我们不希望为我们所服务的每个页面进行数据库查询。 (我们的应用程序安装在一家公司使用,所以用户的全名不被视为“安全敏感”。)所以,如果你认为会话caching因用户拥有的cookie而异,没有太大的错误。
默认的TempData提供程序使用会话,所以实际上没有什么区别,除了在下一个请求结束时清除TempData。 当数据只需要在两个请求之间保持时,您应该使用TempData,最好是第二个是redirect,以避免来自用户的其他请求的问题 – 例如,来自AJAX–意外删除数据。 如果数据需要持续更长时间,则应该重新填充TempData或直接使用Session。
“不起作用”不是很具描述性,但让我提供一些build议。
在底层,TempData使用会话来存储值。 所以在存储机制或类似的方面没有太大的区别。 但是,TempData只会持续到收到下一个请求。
如果用户在表单post之间发出ajax请求,TempData就消失了。 任何请求将清除TempData。 所以当你进行手动redirect的时候,它确实是可靠的。
为什么不能简单地将会议ID渲染到视图窗体中的隐藏字段? 您已经将其添加到模型中。 或者,将其添加到您的路线作为参数。
您可以根据您的要求使用它。 澄清可以是,
TempData与会话
TempData的
- TempData允许我们在单个后续请求期间保存数据。
- 一旦连续请求返回结果,ASP.net MVC将自动终止tempdata的值(这意味着,它只在目标视图完全加载之前一直存在)。
- 它仅适用于当前和随后的请求
-
TempData有Keep方法保留TempData的值。
例:
TempData.Keep(),TempData.Keep(“EmpName”)
-
TempData内部将该值存储到Sessionvariables中。
- 它仅用于存储一次性消息,如validation消息,错误消息等
会议:
- 会话可以存储更长的时间,直到用户会话不过期。
- 会话超时后会话将过期。
- 它适用于所有请求。
- N / A
- 会话variables存储在SessionStateItemCollection对象中(通过页面的HttpContext.Session属性公开)。
- 它被用来存储长寿命的数据,如用户ID,angular色ID等,这些都是在用户会话期间需要的。
TempData和会话,都需要用于获取数据的types转换,并检查空值以避免运行时exception。
我更喜欢在页面中保留这种数据。 将会议ID渲染为隐藏input,以便将其提交回控制器。 处理post的控制器可以将该会议ID反馈给任何将被呈现的视图,以便只要您需要,meetingID基本上都会被传递。
这有点像在调用一个将要在其上运行的方法之前将值存储在全局variables中,而不是直接将值传递给方法。
我会build议MvcContrib的解决scheme: http ://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/
如果你不想要完整的MvcContrib,解决scheme只有1个方法+ 1类,你可以轻松地从MvcContrib的来源获取。
TempData属性值存储在会话状态中。 TempData的值一直保持到读取或直到会话超时为止。 如果你想传递数据一个控制器视图到另一个控制器视图,那么你应该使用TempData。
当数据需要整个应用程序时使用会话