asp.net-mvc 何时在 ASP.Net MVC 中使用 TempData 与 Session
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1500402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use TempData vs Session in ASP.Net MVC
提问by scottm
I am trying to get the hang of MVC framework so bear with me.
我正在尝试掌握 MVC 框架的窍门,所以请耐心等待。
Right now, the only thing I'm using the session store for is storing the current logged in user. My website is simple. For this example, consider three domain objects, Person, Meeting, and File. Users can log in and view a "members only" profile of a meeting and can add files to it, or view a meeting's public "profile" if they aren't logged in.
现在,我使用会话存储的唯一目的是存储当前登录的用户。我的网站很简单。对于此示例,请考虑三个域对象:人员、会议和文件。用户可以登录并查看会议的“仅限会员”个人资料,也可以向其中添加文件,或者如果他们未登录,则可以查看会议的公开“个人资料”。
So, from the meeting's private profile, with a logged in user, I have a "add files" link. This link routes to FileContoller.Add(int meetingId). From this action, I get the meeting the user want to add files to using the meeting id, but after the form is posted, I still need to know which meeting the user is adding files to. That's where my question lies, should I pass the "currently interacting with" meeting through TempData, or add it to the Session store?
因此,从会议的私人资料中,使用登录用户,我有一个“添加文件”链接。此链接路由到 FileContoller.Add(int meetingId)。从这个操作中,我得到了用户想要使用会议 id 添加文件的会议,但是在表单发布后,我仍然需要知道用户正在向哪个会议添加文件。这就是我的问题所在,我应该通过 TempData 传递“当前正在与之交互”的会议,还是将其添加到会话存储中?
This is how I currently have the Add action setup, but it's not working:
这就是我目前设置添加操作的方式,但它不起作用:
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});
}
Edit:
编辑:
Based on most of the answers, can any one provide any examples on what kind of data (other than messages) should be stored in TempData vs Session?
基于大多数答案,任何人都可以提供有关应在 TempData 与 Session 中存储哪种数据(消息除外)的任何示例吗?
回答by Craig Stuntz
TempData is session, so they're not entirely different. However, the distinction is easy to understand, because TempData is for redirects, and redirects only. So when you set some message in TempData and then redirect, you are using TempData correctly.
TempData 是会话,所以它们并不完全不同。但是,区别很容易理解,因为TempData 是用于重定向的,并且仅用于重定向。因此,当您在 TempData 中设置一些消息然后重定向时,您正在正确使用 TempData。
However, using Session for any kind of security is extremely dangerous. Session and Membership are entirely separate in ASP.NET. You can "steal" sessions from other users, and yes, people do attack web sites this way. So if you want to selectively stop a post information based on whether a user is logged in, look at IsAuthenticated, and if you want to selectively show information based on what type of user is logged in, you use a Role provider. Because GETs can be cached, the onlyway to selectively allow access to an action in a GET is with AuthorizeAttribute.
但是,将 Session 用于任何类型的安全都是极其危险的。会话和成员资格在 ASP.NET 中是完全分开的。您可以“窃取”其他用户的会话,是的,人们确实会以这种方式攻击网站。因此,如果您想根据用户是否登录有选择地停止发布信息,请查看IsAuthenticated,如果您想根据用户登录的类型有选择地显示信息,则使用Role provider。因为可以缓存 GET,所以有选择地允许访问 GET 中的操作的唯一方法是使用 AuthorizeAttribute。
UpdateIn response to your edited question: You already have a good example of using TempData in your question, namely, returning a simple error message after a failed POST. In terms of what shouldbe stored in Session (beyond "not much"), I just think of Session as a user-specific cache. Like the non-user-specific Cache, you should not put security-sensitive information there. But it's a good place to stick stuff which is relatively expensive to look up. For example, our Site.Master has the user's full name displayed on it. That is stored in a database, and we don't want to do a database query for it for every page we serve. (An installation of our application is used in a single company, so a user's full name is not considered "security-sensitive.") So if you think of Session as a cache which varies by a cookie which the user has, you won't be far wrong.
更新响应您编辑的问题:您已经有一个在问题中使用 TempData 的好例子,即在 POST 失败后返回一条简单的错误消息。在什么方面应该存储在 Session 中(除了“不多”),我只是将 Session 视为用户特定的缓存。与非用户特定的缓存一样,您不应将安全敏感信息放在那里。但这是一个放置查找相对昂贵的东西的好地方。例如,我们的 Site.Master 上显示了用户的全名。它存储在数据库中,我们不想为我们服务的每个页面都进行数据库查询。(我们的应用程序安装在一家公司中使用,因此用户的全名不被视为“安全敏感”。)因此,如果您将 Session 视为缓存,它会因用户拥有的 cookie 而有所不同,您将不会大错特错。
回答by tvanfosson
The default TempData provider uses the session so there really isn't much of a distinction, except that your TempData is cleared out at the end of the next request. You should use TempData when the data needs only to persist between two requests, preferably the second one being a redirect to avoid issues with other requests from the user -- from AJAX, for example -- deleting the data accidentally. If the data needs to persist longer than that, you should either repopulate the TempData or use the Session directly.
默认的 TempData 提供程序使用会话,因此实际上没有太大区别,只是您的 TempData 在下一个请求结束时被清除。当数据只需要在两个请求之间保持时,您应该使用 TempData,第二个请求最好是重定向,以避免来自用户的其他请求(例如来自 AJAX 的请求)意外删除数据。如果数据需要持续更长的时间,您应该重新填充 TempData 或直接使用 Session。
回答by iamCR
You can use it as per your requirement. A clarification can be,
您可以根据需要使用它。澄清可以是,
TempDataVs Session
临时数据与会话
TempData
临时数据
- TempData allow us to persisting data for the duration of single subsequent request.
- ASP.net MVC will automatically expire the value of tempdata once consecutive request returned the result (it means, it alive only till the target view is fully loaded).
- It valid for only current and subsequent request only
TempData has Keep method to retention the value of TempData.
Example:
TempData.Keep(), TempData.Keep(“EmpName”)
TempData internally stored the value in to Session variable.
- It is used to stored only one time messages like validation messages, error messages etc.
- TempData 允许我们在单个后续请求期间保留数据。
- 一旦连续请求返回结果,ASP.net MVC 将自动使 tempdata 的值过期(这意味着,它只在目标视图完全加载之前活着)。
- 它仅对当前和后续请求有效
TempData 有 Keep 方法来保留 TempData 的值。
例子:
TempData.Keep(), TempData.Keep(“EmpName”)
TempData 在内部将值存储在 Session 变量中。
- 它用于仅存储一次消息,如验证消息、错误消息等。
Session:
会议:
- Session is able to store data much more long time, until user session is not expire.
- Session will be expire after the session time out occurred.
- It valid for all requests.
- N/A
- Session varible are stored in SessionStateItemCollection object (Which is exposed through the HttpContext.Session property of page).
- It is used to stored long life data like user id, role id etc. which required throughout user session.
- 会话能够将数据存储更长时间,直到用户会话未过期。
- 会话将在会话超时发生后过期。
- 它对所有请求都有效。
- 不适用
- 会话变量存储在 SessionStateItemCollection 对象中(通过页面的 HttpContext.Session 属性公开)。
- 它用于存储整个用户会话所需的长寿命数据,如用户 ID、角色 ID 等。
TempData and session, both required typecasting for getting data and check for null values to avoid run time exception.
TempData 和 session 都需要类型转换来获取数据并检查空值以避免运行时异常。
回答by womp
"It doesn't work" isn't very descriptive, but let me offer a couple suggestions.
“它不起作用”不是很具有描述性,但让我提供一些建议。
Under the hood, TempData uses Session to store values. So there isn't much difference in terms of storage mechanisms or anything like that. However, TempData only lasts until the next request is received.
在幕后,TempData 使用 Session 来存储值。所以在存储机制或类似的东西方面没有太大区别。但是,TempData 仅持续到接收到下一个请求。
If the user makes an ajax request in between form posts, TempData is gone. Any request whatsoever will clear TempData. So it's really only reliable when you're doing a manual redirect.
如果用户在表单发布之间发出 ajax 请求,TempData 就会消失。任何请求都将清除 TempData。因此,只有在您进行手动重定向时才真正可靠。
Why can't you just simply render the meeting ID to a hidden field in your View form? You're already adding it to the model. Alternately, add it to your route as a parameter.
为什么不能简单地将会议 ID 渲染到视图表单中的隐藏字段?您已经将其添加到模型中。或者,将其作为参数添加到您的路线中。
回答by RedFilter
I prefer to maintain that kind of data in the page itself. Render meetingID as a hidden input, so it gets submitted back to the controller. The controller handling the post can then feed that meeting ID back to whatever view will be rendered, so that the meetingID basically gets passed around as long as you need it.
我更喜欢在页面本身中维护这种数据。将 meetingID 渲染为隐藏输入,以便将其提交回控制器。然后,处理帖子的控制器可以将该会议 ID 反馈给将要呈现的任何视图,这样只要您需要,会议 ID 基本上就会被传递。
It's kind of like the difference between storing a value in a global variable before calling a method that will operate on it, vs. passing the value directly to the method.
这有点像在调用将对其进行操作的方法之前将值存储在全局变量中与将值直接传递给方法之间的区别。
回答by queen3
I would suggest MvcContrib's solution: http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/
我建议 MvcContrib 的解决方案:http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/
If you don't want full MvcContrib, the solution is only 1 method + 1 class that you can easily grab from MvcContrib sources.
如果您不想要完整的 MvcContrib,解决方案只有 1 个方法 + 1 个类,您可以轻松地从 MvcContrib 源中获取。
回答by Mervin
The TempData property value is stored in session state. The value of TempData persists until it is read or until the session times out. If you want pass data one controller view to another controller view then you should use TempData.
TempData 属性值存储在会话状态中。TempData 的值一直存在,直到它被读取或直到会话超时。如果要将数据从一个控制器视图传递到另一个控制器视图,则应使用 TempData。
Use Session when the data need for the throughout application
当整个应用程序需要数据时使用Session

