仍然可以在 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 变量,或者对于某些事情(比如购物车)有更好的选择的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 .net 4 中部署我的 ASP.NET MVC 4 应用程序吗
在ASP.NET MVC中全局应用JSON Serializer设置