何时在 ASP.Net MVC 中使用 TempData 与 Session

发布于 2024-08-05 20:18:29 字数 1865 浏览 5 评论 0原文

我正在尝试掌握 MVC 框架,所以请耐心等待。

现在,我使用会话存储的唯一目的是存储当前登录的用户。我的网站很简单。对于此示例,请考虑三个域对象:人员、会议和文件。用户可以登录并查看会议的“仅限会员”个人资料,并且可以向其中添加文件,或者如果未登录,则可以查看会议的公共“个人资料”。

因此,从会议的私人个人资料中,通过登录用户,我有一个“添加文件”链接。此链接路由至 FileContoller.Add(int meetId)。通过此操作,我可以使用会议 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 与 Session 中?

I am trying to get the hang of MVC framework so bear with me.

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?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

绳情 2024-08-12 20:18:29

TempData 是会话,因此它们并不完全不同。不过,区别很容易理解,因为 TempData 用于重定向,并且仅重定向。因此,当您在 TempData 中设置一些消息然后重定向时,您就正确使用了 TempData。

然而,将 Session 用于任何类型的安全都是极其危险的。会话和成员资格在 ASP.NET 中是完全独立的。 您可以“窃取”其他用户的会话,是的,人们确实以这种方式攻击网站。因此,如果您想根据用户是否登录有选择地停止发布信息,请查看 IsAuthenticated,如果您想根据登录的用户类型有选择地显示信息,请使用 角色提供程序。由于 GET 可以缓存,因此有选择地允许访问 GET 中的操作的唯一方法是使用 AuthorizeAttribute。

更新针对您编辑的问题:您已经有一个在问题中使用 TempData 的好示例,即在 POST 失败后返回简单的错误消息。就 Session 中应该存储的内容(除了“不多”之外)而言,我只是将 Session 视为特定于用户的缓存。与非用户特定的缓存一样,您不应将安全敏感信息放在那里。但这是一个放置查找相对昂贵的东西的好地方。例如,我们的Site.Master上显示了用户的全名。它存储在数据库中,我们不想为我们服务的每个页面都对其进行数据库查询。 (我们的应用程序的安装是在一家公司中使用的,因此用户的全名不被视为“安全敏感”。)因此,如果您将 Session 视为一个缓存,该缓存随用户拥有的 cookie 的不同而变化,那么您就不会'不会错的。

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.

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 only way to selectively allow access to an action in a GET is with AuthorizeAttribute.

Update In 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 should be 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.

人│生佛魔见 2024-08-12 20:18:29

默认的 TempData 提供程序使用会话,因此实际上没有太大区别,只是您的 TempData 在下一个请求结束时被清除。当数据只需要在两个请求之间保留时,您应该使用 TempData,第二个请求最好是重定向,以避免用户的其他请求(例如来自 AJAX)出现问题,意外删除数据。如果数据需要保留的时间超过该时间,您应该重新填充 TempData 或直接使用 Session。

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.

独留℉清风醉 2024-08-12 20:18:29

您可以根据您的要求使用它。需要澄清的是,

TempDataSession

TempData

  1. TempData 允许我们在单个后续请求的持续时间内保留数据。
  2. 一旦连续请求返回结果,ASP.net MVC 将自动使 tempdata 的值过期(这意味着,它仅在目标视图完全加载之前才有效)。
  3. 仅对当前和后续请求有效
  4. TempData 有 Keep 方法来保留 TempData 的值。

    示例:

    TempData.Keep(), TempData.Keep(“EmpName”)

  5. TempData 在内部将值存储到 Session 变量。

  6. 它用于仅存储一次消息,如验证消息、错误消息等。

Session:

  1. Session 能够存储数据更长时间,直到用户会话未过期。
  2. 会话超时后,会话将过期。
  3. 它对所有请求都有效。
  4. N/A
  5. Session 变量存储在 SessionStateItemCollection 对象中(通过页面的 HttpContext.Session 属性公开)。
  6. 它用于存储整个用户会话所需的长期数据,例如用户 ID、角色 ID 等。

TempData 和 session 都需要进行类型转换来获取数据并检查空值以避免运行时异常。

You can use it as per your requirement. A clarification can be,

TempData Vs Session

TempData

  1. TempData allow us to persisting data for the duration of single subsequent request.
  2. 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).
  3. It valid for only current and subsequent request only
  4. TempData has Keep method to retention the value of TempData.

    Example:

    TempData.Keep(), TempData.Keep(“EmpName”)

  5. TempData internally stored the value in to Session variable.

  6. It is used to stored only one time messages like validation messages, error messages etc.

Session:

  1. Session is able to store data much more long time, until user session is not expire.
  2. Session will be expire after the session time out occurred.
  3. It valid for all requests.
  4. N/A
  5. Session varible are stored in SessionStateItemCollection object (Which is exposed through the HttpContext.Session property of page).
  6. It is used to stored long life data like user id, role id etc. which required throughout user session.

TempData and session, both required typecasting for getting data and check for null values to avoid run time exception.

夜夜流光相皎洁 2024-08-12 20:18:29

“它不起作用”并不是很具有描述性,但让我提供一些建议。

在底层,TempData 使用 Session 来存储值。因此,在存储机制或类似方面没有太大区别。但是,TempData 仅持续到收到下一个请求为止。

如果用户在表单发布之间发出 ajax 请求,TempData 就会消失。任何请求都会清除 TempData。因此,只有在进行手动重定向时它才可靠。

为什么不能简单地将会议 ID 呈现到视图表单中的隐藏字段中?您已经将其添加到模型中。或者,将其作为参数添加到您的路线中。

"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.

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.

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.

你曾走过我的故事 2024-08-12 20:18:29

我更喜欢在页面本身中维护此类数据。将 MeetingID 渲染为隐藏输入,以便将其提交回控制器。然后,处理帖子的控制器可以将该会议 ID 反馈给将呈现的任何视图,这样只要您需要,会议 ID 基本上就会被传递。

这有点像在调用对其进行操作的方法之前将值存储在全局变量中与将值直接传递给方法之间的区别。

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.

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.

若无相欠,怎会相见 2024-08-12 20:18:29

我建议 MvcContrib 的解决方案:
http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/

如果你不想完整MvcContrib,解决方案只是 1 个方法 + 1 个类,您可以轻松地从 MvcContrib 源中获取它们。

I would suggest MvcContrib's solution:
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.

耀眼的星火 2024-08-12 20:18:29

TempData 属性值存储在会话状态中。 TempData 的值将一直存在,直到被读取或会话超时。如果要将数据从一个控制器视图传递到另一个控制器视图,那么您应该使用 TempData。

当整个应用程序需要数据时使用Session

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.

Use Session when the data need for the throughout application

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文