仍然可以在 ASP.NET mvc 中使用 Session 变量,或者对于某些事情(比如购物车)有更好的选择

Posted

技术标签:

【中文标题】仍然可以在 ASP.NET mvc 中使用 Session 变量,或者对于某些事情(比如购物车)有更好的选择【英文标题】:Still ok to use Session variables in ASP.NET mvc, or is there a better alternative for some things (like a cart) 【发布时间】:2011-10-08 08:08:42 【问题描述】:

我有一种情况,我需要通过多个页面访问购物车。 因此,在产品页面上 - 创建购物车并添加一些商品 在购物车结帐页面上 - 确认帐单地址 在购物车结帐后 - 进行最后检查,将购物车添加到数据库并开始付款

我的问题是,绕过购物车的最佳方式是什么?

我尝试将购物车从页面传递到回发并保持所有值有效,但是在某些页面(帐单地址确认页面)上,这似乎很麻烦,我只想检查帐单地址而不是真的希望页面上的大量 HiddenFor() 再次填充购物车

TempData[] 是我用于产品结帐页面的,然后想知道是否最好一直设置 TempData ......

你可以只使用会话变量吗?

出于某种原因,我读到使用 Session 并不是很好的做法,因此提出了这个问题。

感谢您的指导,如果您认为有帮助,我很乐意提供一些代码/更多信息。

【问题讨论】:

最佳答案来自@NightOwl888 “对于购物车,您绝对不应该使用会话状态” 【参考方案1】:

在 ASP.NET MVC 中使用会话是完全可以的,尤其是在您的购物车场景中。

使用会话有一些缺点,但它们似乎不适用于您的情况:

1) 会话阻止用户从多个浏览器选项卡正确浏览您的网站,在一个选项卡中所做的更改会反映在所有其他选项卡中。 但有了购物车,这正是您所需要的。您不需要每个用户有多个购物车,对吗?

2) 默认情况下会话不会持久化,如果您在 webfarm 上操作,则需要将会话保存在数据库中,以便每个场节点都可以访问。 但是您似乎不太可能像这样缩放。如果您满足扩展的必要性,会话将不是您的首要问题。

3) 会话需要用户浏览器的附加功能(通常是 cookie)。但是现代浏览器都支持 cookie,所以你只需要担心非常特殊的浏览器。

会话相对于隐藏输入还有一些好处:

1) 较小的开销。只有一个小的会话 cookie 在您和客户端之间来回传递,而不是完整的隐藏输入集。

2) 更简单的编程。您不必确保在每个页面中都包含隐藏的输入。

3) 安全性。客户可以随意更改隐藏输入的内容。您无法通过隐藏输入轻松传递敏感信息,您需要对其进行加密。会话值存储在服务器上,因此客户端无权访问它们。

【讨论】:

【参考方案2】:

会话很好,但考虑一下亚马逊风格的系统,即使您没有登录,您也会收到一个识别 cookie。这允许他们将您的购物篮存储在数据库中,并针对识别 cookie 键入。

结果是您避免了由于会话超时/服务器应用程序域回收而丢失购物篮的可怕用户体验(后者通过使用 SQLState 会话存储得到缓解,我建议这样做)。用户可以在几天后回来,他们的购物篮仍然在那里。除非这是一个安全/隐私问题,否则我认为这是更好的解决方案。

【讨论】:

【参考方案3】:

在 asp.net mvc 应用程序中使用 session 是非常好的。史蒂夫·桑德森在他的书附带的示例应用程序中使用了购物车会话。代码是available here

【讨论】:

+1 - 仍然可以使用会话,但需要注意不要像网络表单中的规范那样过度使用它。胖次会议仍然不是一件好事。 我的意思是在需要的地方使用。正如 Zurty 解释的那样,我们不应该过度使用它。 cart 是需要使用 session 的完美场景之一【参考方案4】:

我会使用 Session,除非有理由避免它。

例如,我有一个项目,我在后台重复调用 MVC 操作。此操作提供文件,该文件在网络上很慢。我曾经使用过 Session,但我很快发现了主要的不利影响:IIS 不会并行执行来自同一用户的调用,而是一个接一个地依次执行。这对性能产生了巨大影响,因此我使用了另一种方法:我将 HttpContext.User.Identity 设置为用户名,并将其用作从数据库中获取内容的键。但是你可以将它设置为一些随机的 GUID 并用它来替换 Sessions。

【讨论】:

确实,对于启用了 Session 的 ASP.NET 页面和一般的 MVC 控制器,由于会话锁定,同一用户的 HTTP 请求是同步的。但是在 MVC 3 中,您可以通过使用 SessionState 属性来控制控制器的会话使用特性。例如,要完全在控制器上限制会话的使用,从而允许异步调用(例如,用于 AJAX 轮询或文件服务),您可以使用 [SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)]。欲了解更多信息:tech-journals.com/jonow/2011/10/22/…【参考方案5】:

对于购物车,您绝对应该不要使用会话状态。一种合理的方法是使用Anonymous Identification Module 为您管理cookie。您只需要web.config 中的一行。

<system.web>
    <anonymousIdentification enabled="true" />
</system.web>

然后,对于每个请求,您都可以使用 Request.AnonymousID 属性(它返回一个表示 GUID 的字符串)在数据库中查找购物车。

public ActionResult ShowCartDetails()

    var CartId = new Guid(Request.AnonymousID);

    // Lookup cart...

    return View();

这不仅比使用会话状态更高效,而且更简单。

参考资料:

http://brockallen.com/2012/04/07/think-twice-about-using-session-state/ http://forums.asp.net/t/1785321.aspx?Stored+Shopping+Cart+for+unknown+user

【讨论】:

【参考方案6】:

我倾向于使用将我的购物车序列化为 base64 string 的 cookie,这似乎工作得很好

【讨论】:

对会话变量执行此操作有什么好处? 优点:减少服务器上的存储负载,避免会话超时问题。缺点:HTTP 流量增加,需要更多安全检查以防止恶意修改 cookie 数据。还要记住,cookie 中存储的数据大小是有限制的:myownplayground.atspace.com/cookietest.html @Zootius 说了什么。我不是说你应该这样做,只是提供另一种选择【参考方案7】:

在购物车系统中,添加到购物车的产品非常重要,因此在我看来使用会话不是一个好主意。在数据库中使用 cookie 和临时表是最好的主意之一。我们可以永久存储这些数据,也可以在某些天后清除。

【讨论】:

以上是关于仍然可以在 ASP.NET mvc 中使用 Session 变量,或者对于某些事情(比如购物车)有更好的选择的主要内容,如果未能解决你的问题,请参考以下文章

在 Asp.Net MVC 中验证自定义用户类

我可以在 .net 4 中部署我的 ASP.NET MVC 4 应用程序吗

如何在 ASP.NET MVC 中组织 DAL [关闭]

在ASP.NET MVC中全局应用JSON Serializer设置

如何在不刷新的情况下使用Ajax在ASP.NET MVC中保存表单数据

如何在不刷新的情况下使用 Ajax 在 ASP.NET MVC 中保存表单数据