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

sco*_*ttm 60 asp.net-mvc session tempdata

我试图搞清楚MVC框架,所以请耐心等待.

现在,我唯一使用会话存储的是存储当前登录的用户.我的网站很简单.对于此示例,请考虑三个域对象:Person,Meeting和File.用户可以登录并查看会议的"仅限会员"个人资料,并可以向其添加文件,或查看会议的公共"个人资料"(如果他们未登录).

因此,从会议的私人资料中,登录用户,我有一个"添加文件"链接.此链接路由到FileContoller.Add(int meetingId).通过此操作,我获得了用户希望使用会议ID添加文件的会议,但在发布表单后,我仍然需要知道用户正在向哪个会议添加文件.这就是我的问题所在,我应该通过TempData传递"当前正在与之交互"会议,还是将其添加到会话存储中?

这就是我目前的添加操作设置,但它不起作用:

    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});
}
Run Code Online (Sandbox Code Playgroud)

编辑:

基于大多数答案,任何人都可以提供关于哪些数据(除了消息)应该存储在TempData vs Session中的任何示例?

Cra*_*ntz 89

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

但是,对任何类型的安全使用Session都是非常危险的.会话和成员资格在ASP.NET中是完全独立的.你可以"窃取"其他用户的会话,是的,人们会以这种方式攻击网站.因此,如果要根据用户是否登录选择性地停止发布信息,请查看IsAuthenticated,如果要根据登录的用户类型有选择地显示信息,请使用角色提供程序.因为可以缓存GET,所以选择性地允许访问GET中的操作的唯一方法是使用AuthorizeAttribute.

更新响应您编辑的问题:您已经有一个在问题中使用TempData的好例子,即在POST失败后返回一条简单的错误消息.就应该存储在Session中的内容而言(超出"不多"),我只想将Session视为用户特定的缓存.与非特定于用户的Cache一样,您不应将安全敏感信息放在那里.但这是一个很好的地方来粘贴相对昂贵的东西.例如,我们的Site.Master上显示了用户的全名.它存储在数据库中,我们不希望为我们服务的每个页面都进行数据库查询.(我们的应用程序的安装在单个公司中使用,因此用户的全名不被视为"安全敏感".)因此,如果您将Session视为缓存,该缓存因用户拥有的cookie而异,您就赢了远远错了.

  • 鉴权机制不是基于cookie的,难道不能用类似的方式窃取吗? (2认同)
  • @Ismail,是的,涉及一个cookie(默认情况下).不,它不能以类似的方式被盗.身份验证旨在确保安全.会议不是.他们是两个不同的东西. (2认同)

tva*_*son 17

默认的TempData提供程序使用会话,因此除了在下一个请求结束时清除TempData之外,确实没有太大的区别.当数据只需要在两个请求之间保持时,你应该使用TempData,最好是第二个是重定向,以避免来自用户的其他请求 - 例如AJAX - 意外删除数据.如果数据需要持续的时间超过该数据,则应重新填充TempData或直接使用Session.

  • 不,你不能算数.TempData仅用于重定向.如果你在GET中设置TempData,那么你的页面会进行AJAX调用,然后用户POST,TempData就会消失.* (3认同)

iam*_*mCR 6

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

临时数据会话

临时数据

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

    例子:

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

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

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

会议:

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

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