Mar*_*ark 48 asp.net-mvc session session-variables asp.net-mvc-3 asp.net-mvc-4
好吧,首先,在任何人试图确定这是一个"重复"的问题之前; 我已经回顾了关于类似问题的大部分关于SO的帖子,但即使结合所有已经说过的话,我仍然有点处于最终的困境,或者我应该就此达成一致意见.
然而,我可以说我(基于帖子)最终确定答案是基于要求的范围.但即使考虑到这一点,我的意见似乎也太多了,我无法决定如何处理这个问题.
我的直接要求是我需要在许多视图中保持来自1个控制器的可变数据.更具体地说,我有一个控制器和相应的视图来处理购物车项目计数,我想在多个视图中保留这些数据.我认为_layout视图是最合乎逻辑的选择.
现在我已成功完成此任务,方法是将值赋给从我的_layout视图中检索的Session变量; 因此,即使用户要浏览网站内的任何位置,购物车中的商品数量仍将持续,直到他们离开网站或完成结帐; 在这种情况下,变量将在代码中清除.
我读过的帖子似乎偏向于远离Session变量而支持Cookie并将数据存储在数据库中; 或者声明为了我建议使用它们的目的,Session变量可以很好地使用.
我读过的另一件事表明,如果网站上的流量很高,会话变量可能会阻碍整体性能,因为信息存储在服务器上.
我个人无法证明在数据库中存储此类信息并随后访问数据库是合理的,因为我认为这也会影响网站性能,并且对于临时数据的存储似乎有点过分.TempData,ViewData和ViewBag不能用于持久保存数据,因此它们不是IMO要求的逻辑选择.
如果还有另一个非常适合Session变量的替代品(这对我有用),我想知道它是什么.
在提供最佳建议方面似乎相互矛盾的2个帖子让我有些困惑.
缺点:避免在ASP.NET MVC中使用会话状态是一种好习惯吗?如果是,为什么以及如何?
优点:仍然可以在ASP.NET mvc中使用Session变量,或者对某些东西有更好的选择(比如购物车)
似乎这个问题(虽然以许多不同的变体形式呈现)没有明确的答案,我可以得出结论.
如果有一种更优选的方式来实现这一点而没有过度杀伤,那么这就是我正在寻找的答案.
我在某处读到了MVC过滤器与Global.ascx应用程序启动部分的结合使用,但这似乎不适合在控制器级别设置的变量和静态变量一样多.
有人可能会对这个主题提出许多不同的意见(可能是因为缺少一个更好的词)吗?也许可以为这个问题提供更明确的答案?我确信各种各样的意见都有它们的位置,我并不是在试图抹黑它们.但是,拥有明确且可能一致的答案会更好; 然后我可以对其他帖子进行排序,以确定最适合我的应用程序的内容.
当然,如果这个问题没有明确的答案; 告诉我,我会尝试从其他帖子中得出我自己的答案.
谢谢
================================================== =========
缓存和Cookie似乎是响应的一般偏好,但我也注意到缓存它不是在多个Web服务器上使用的理想候选者的声明,因为同步可能是一个潜在的问题.
值得称赞的是Tim,它表示数据库存储已经过优化,用户可以选择稍后返回并继续停止.
这是一个很好的观点,但对可能性保持远见; 一些用户可能无法返回,在数据库中留下不必要的数据,这可能是合理的.
因此,保持数据库优化和清洁("对我而言"具有相同的相关性)将需要实施维护任务,以根据设定的时间阈值自动使这些记录到期以考虑这些情况.虽然维护任务不是一个不容置疑的选择,但我仍然认为这仅仅为了作为临时存储的意图目的而增加了一些工作量.
尽管如此,我确实尊重蒂姆的建议,并认为在一定程度上反对我的初步意见是值得的.数据库似乎不是存储临时数据的可行选择; 所以我认为折衷方案是将数据存储在数据库中(考虑到购物车或类似的场景),可能是在结账后.正如您之前所述,这种方式可能会在后续访问时持续跟踪数据,因此您可以记录交易记录.但更重要的是,这些交易的数据与持久存在于数据库中具有真正相关性.
还有人说,尽管Session比数据库快; 但是,尽管有一些警告可以在某种程度上通过其他机制来缓解,例如利用SessionStateBehavior属性,仅作为一个例子.
但是......我认为Erik有点像Dunning-Kruger效应一样带回家.虽然,从这里给出的答案的内容和解释; 我严重怀疑任何回应的人的专业知识是否有问题.尽管如此,我倾向于同意这样一个事实:获得一致意见可能比我的合理期望高一些.
我更具体地寻找的是对一种技术的普遍共识,该技术可以舒适地适应不同的场景.换句话说,这些东西不仅可以适应我的特定场景,还可以为具有潜在更大流量的大型环境提供可扩展性元素.这样,编程的改变可以完全减轻或最小化.
==================================================
会话变量似乎适应较小的案例场景,并且在适用的情况下,但它们有一些潜在的持久性问题,以及其他值得注意的差异,正如Erik所说的非常彻底.所以这个选项显然不适合可扩展的模型.
缓存优于会话变量,但同样不是"最佳"可伸缩选项,这是由于Web服务器场环境中潜在的同步复杂性,如前所述.但仍然是一个选择.
数据库存储是可扩展的,但出于临时易失性存储的目的,从数据库的角度来看可能不是最优雅的选择,因为它需要定期清理.就个人而言,在我职业生涯早期拥有强大的数据库概念基础,这可能不会成为许多开发人员可能同意的事情.但是从程序员的角度来看,为此目的使用数据库可能足以满足Web开发的需要; 但是从DAL和DB开发的角度来看,这(对我而言)有可能强制执行额外的DB任务来强制执行有效的后端.
Cookie似乎是一个很好的选择,具有Session变量和缓存的"理想"元素.
==================================================
根据答案; 我认为COOKIES和CACHING似乎通常是全面的最佳实践建议,结合数据库存储,事后需要持续的持久性; 作为提供的可扩展性的潜在良好候选者.
2之间的最终选择似乎是基于需要存储的数据的数量和类型(例如敏感与非敏感以及是否存在客户可能改变其数据的担忧); 除了COOKIES的特殊考虑之外,它们可能会被客户禁用.
显然,从提供的答案中明确指出并得出结论,但在可扩展性方面,没有一个适合所有解决方案的解决方案; 我可能错了,但这些似乎是最好的选择.
因为所有的反应都很好; 我相当赞同所有帖子都有用,并接受Erik的答案作为一个全面的整体可扩展解决方案.我希望我可以选择多个已接受的答案,因为我相信蒂姆的回答也非常清晰和简洁.
古普塔的反应也不错,但我想更详细地提出建议的答案,而不是重复以前的帖子.
多谢你们!
Eri*_*sch 26
你永远不会对任何一大群人的任何事情达成一致意见.那只是人性.其中一部分源于邓宁克鲁格效应,该效应表明,一个人对某个主题的了解越少,他们就越有可能过分重视他们在该主题中的专业知识.换句话说,很多人认为他们知道某些事情,但仅仅因为他们不知道他们不知道.部分原因是人们有不同的经历,有些人发现会话没有问题,而有些则有不同的情况,反之亦然......
因此,为了备份您的研究,这表明答案在很大程度上取决于要求,我们需要了解您的要求是什么.如果这是一个高流量站点,在Web场中使用负载平衡服务器,则尽可能远离会话.当然,可以在服务器场环境(会话服务器,分发缓存服务器等)中以各种方式共享会话,但如果您可以帮助它,则避免会话几乎总是更快.
如果您的站点是单个服务器,并且不太可能超出该服务器.而且您的流量模式相对较低,那么会话可能是一个有用的选择.但是,您应始终注意会话存储不可靠,并且可能随时消失.如果应用程序池被回收,会话就会消失.如果未捕获的异常冒泡到工作进程,则会话可能会消失.如果IIS认为内存不足,则无论配置了什么超时值,您的会话都可能会消失.您也无法始终获得会话已结束的可靠通知,因为已终止的会话不会触发Session_End事件.
另一个问题是Session是序列化的.换句话说,IIS一次阻止多个线程写入会话,并且它通常通过在线程运行时锁定会话(如果它没有选择退出可写会话锁定)来执行此操作.这在某些情况下会导致严重的问题,而在其他情况下则会导致性能不佳.如果您不打算在该方法中修改它,可以通过使用只读会话属性标记各种方法来缓解此问题.
最终,如果您确实选择使用会话,那么尽量只使用它来处理小的,短暂的事情,如果不可能,那么在会话丢失的情况下构建一种"重新生成"数据的方法.例如,使用购物车示例中的项目数量,您可以编写一个方法,首先检查该值是否存在,如果不存在,则将其从数据库中加载.始终使用此方法来访问变量,而不是直接从会话访问它...这样,如果会话丢失,它只会重新加载它.
但是,说了这个...对于购物车中的商品数量,我通常更喜欢使用cookie来获取此信息,因为cookie无论如何都会在每次加载时传递到页面,这是一个小的离散数据单元.对于您希望阻止用户无法更改的敏感数据,通常更喜欢会话.购物车中的商品数量根本不符合该规则.
Tim*_*ora 10
数据库经过高度优化.像购物车计数这样的简单值是数据库缓存的一个很好的候选者,并且(希望)可以廉价地直接计算.这可能不是问题.
但是,如果您排除了其他机制,那么小的,逐个用户的值是会话的可行候选者.
Cache
适用于站点范围的值,或具有唯一键的用户特定值.但是,跨多个Web服务器同步缓存可能很困难.进程外会话状态将保持同步,因为它存储在单个位置(数据库或状态服务器)中.
当然,有许多第三方缓存备选方案可以使它们保持同步.
无论计数临时存储在何处,我都认为购物车本身应存储在数据库中,以便用户可以选择稍后返回并继续停止.
如果你使用了进程外会话状态的(在负载平衡环境如和/或使会议更耐用),这将创下一个数据库或拨打了过程的服务,但电话是相对便宜的,除非你是序列化大对象图表.
每个请求加载一次会话.后续读取访问速度非常快.
即使没有负载,写入会话也可能对性能有害.为什么?大多数现代应用程序使用异步调用,当多个异步调用命中读取/写入会话的HTTP处理程序(页面,控制器等)时,ASP.Net将锁定会话以序列化访问.为避免这种情况,您可以使用装饰控制器[SessionState( SessionStateBehavior.ReadOnly )]
现在我已成功完成此任务,方法是将值赋给从我的_layout视图中检索的Session变量;
这似乎是混合问题,即让视图意识到底层存储机制.从纯粹主义的角度来看,我会在视图模型上设置此值,或者至少将其放入视图模型中ViewBag
.从实际的角度来看,以这种方式检索的一个或两个值可能不会伤害任何东西,但要注意让它进一步增长.
我在某处读到了MVC过滤器与Global.ascx应用程序启动部分的结合使用,但这似乎不适合在控制器级别设置的变量和静态变量一样多.
静态变量具有完全合法的用途,但您必须彻底了解它们或存在严重问题.
请参阅我在ASP.Net中有关静态变量的答案:
归档时间: |
|
查看次数: |
29158 次 |
最近记录: |