是否有一个最佳做法,并推荐替代MVC中的会话variables
好的,在任何人试图确定这是一个“重复”的问题之前, 我已经回顾了大多数关于类似问题的SO上的post,但即使是所有的说法,我仍然有点困惑于决定性的问题,或者我应该就此一致同意。
但是我可以说我(根据职位)确定地确定答案是基于要求的范围。 但即使考虑到这一点,对于我如何处理这个问题,我的意见也显得太多了。
我的直接要求是,我需要从1个控制器中存储多个视图的可变数据。 更具体地说,我有一个控制器和相应的视图,处理购物车项目计数,我想坚持在多个视图的数据。 我在想,_layout视图是这个最合乎逻辑的select。
现在我已经成功地完成了这个任务,将值赋给一个从我的_layout视图中获取的Sessionvariables; 因此,即使用户在网站内的任何位置导航,购物车中的商品数量也会一直存在,直到他们离开网站或完成结帐; 在这种情况下,variables将在代码中清除。
我读过的post似乎有偏见,要么偏离会话variables,而是支持Cookies并将数据存储在数据库中; 或者说为了我打算使用它们的目的,Sessionvariables是完全可以使用的。
我读过的另一件事表明,如果由于信息存储在服务器上,网站上的stream量很高,会话variables可能会阻碍整体性能。
我个人不能certificate将这种types的信息存储在数据库中,然后敲击数据库,我想这可能会影响网站的性能,对于存储临时数据似乎有点矫枉过正。 TempData,ViewData和ViewBag在保存数据时不起作用,因此它们不是IMO要求的合乎逻辑的select。
如果还有另一个适用于Sessionvariables的替代方法(这对我来说很合适),我想知道它是什么。
2个提供最好build议似乎相互矛盾的post让我有些困惑。
缺点: 避免在ASP.NET MVC中使用会话状态是一个好习惯吗? 如果是,为什么和如何?
优点: 仍然可以在ASP.NET mvc中使用会话variables,或者有一些更好的select(如购物车)
似乎这个问题(尽pipe提出了许多不同的变化)没有我可以总结的明确答案。
如果有更好的方法来完成这个没有过度杀伤,那么这就是我正在寻找的答案。
我同时在Global.ascx应用程序开始部分看到了MVCfilter的使用,但是这对于在控制器级别设置的variables和静态variables可能不太合适。
有人可能会对这个话题提出许多不同的意见,也许会提供一个更确定的答案吗? 我敢肯定,不同的意见有其自己的位置,我不是企图抹黑他们。 但有一个明确的,可能是一致的答案会更好; 那么我可以通过其他职位来确定什么是最适合我的应用程序。
当然,如果这个问题没有确定的答案, 只要告诉我,我会尝试从其他职位得到我自己的答案。
谢谢
================================================== =========
对答复提供了更新的回应
caching和cookies似乎是从响应的一般偏好,但是我也注意到caching它不是一个理想的候选人跨多个Web服务器使用的声明,因为同步可能是一个潜在的问题。
对Tim的评价是,数据库存储已经过优化,用户可以select稍后返回并继续他们离开的地方。
这是一个很好的观点,但要高瞻远瞩。 这可能是合理的,因为有些用户可能不会在数据库中留下不必要的数据。
因此,为了保持数据库的优化和清洁(这对我而言是同等重要的),需要执行维护任务,根据设定的时间阈值自动使这些logging到期以考虑这些情况。 虽然维护任务不是一个不容置疑的select,但我仍然认为这仅仅是为了作为临时存储的目的而增加了一点工作。
尽pipe如此,我还是尊重蒂姆的build议,并认为在一定程度上反驳我的初步意见是值得的。 数据库似乎不是存储临时数据的可行scheme; 所以我认为妥协可能是将数据存储在数据库中(或者在购物车或类似的情况下)或许在结账之后。 就像您之前所说的那样,随后的访问可能会持续跟踪数据,因此您有交易logging。 但更重要的是,这些交易的数据与数据库保持真正的相关性。
还有人表示,尽pipeSession比数据库快, 但是尽pipe有一些警告,可以在某种程度上被其他机制所缓解,例如利用SessionStateBehavior属性,只是作为一个例子。
但是……我认为Erik用Dunning-Kruger效应开了点家。 虽然从这里给出的答案的内容和解释, 我严重怀疑任何回应者的专业知识都是有问题的。 尽pipe如此,我倾向于认同获得一致意见的事实可能比我的预期要高一些。
我更特别要寻找的是能够舒适地适应多种情况的技术的普遍共识。 换句话说,不仅可以适应我特定的情况,而且还可以为具有更大stream量的较大环境提供可扩展性。 通过这种方式,编程中的变化可以完全缓解,也可以最小化。
==================================================
基于反馈的总结:
-
会话variables似乎适用于较小的情况,在适用的情况下,但是它们有一些潜在的持久性问题,除了其他显着的差异之外,正如Erik所说的那样。 所以这个选项显然不适合一个可扩展的模型。
-
caching优于会话variables,但由于Web服务器场环境中潜在的同步复杂性,如前所述,再次不是必需的“最佳”可伸缩选项。 不过还是一个select。
-
数据库存储是可扩展的,但出于临时易失性存储的目的,从数据库的angular度来看可能不是最优雅的select,因为它需要定期清理。 就个人而言,在我的职业生涯早期拥有强大的数据库概念基础,这可能不会是许多开发人员可能会同意的事情; 但是为了这个目的使用数据库可能足以从程序员的angular度来进行Web开发。 不过从DAL和DB开发的angular度来看,这(对我来说)有可能强制执行一个额外的数据库任务来强制执行一个高效的后端。
-
Cookies似乎是一个不错的select,具有会话variables和caching的“合意”元素。
==================================================
结论
根据答案; 我认为,COOKIES和CACHING似乎总体上是全面的最佳实践的build议,与数据库存储相结合,当事后需要持续的持久性时, 作为所提供的可伸缩性的潜在的良好候选者。
2之间的最终select似乎是基于需要存储的数据的数量和types(例如,敏感与非敏感以及是否有客户可能会改变数据的担忧)。 除了COOKIES的特殊考虑因素,可能会被客户禁用。
显然,没有一个解决scheme明确指出,从所提供的答案中得出结论,但在可扩展性方面; 我可能是错的,但这似乎是最好的select。
因为所有的反应都很好。 我相当相信所有的post都是有用的,并且接受Erik的答案是一个全面的可扩展的全面解决scheme。 我希望我可以select不止一个被接受的答案,因为我相信蒂姆的回应也是非常简明的。
古普塔的回答也很好,但我想要更详细的提出答案,而不是重复以前的post。
多谢你们!
在任何一大群人中,你永远不会得到一致的意见。 这只是人性。 部分原因来自于邓宁 – 克鲁格效应(Dunning-Kruger Effect) ,该理论认为,一个人对某个主题的了解越less,他们就越可能高估他们在这个主题上的专业知识。 换句话说,很多人认为他们知道的东西,但只是因为他们不知道他们不知道。 部分原因是人们有不同的经历,有些人发现会议没有问题,有些则有不同的情况,反之亦然。
因此,为了支持您的研究,这表明答案在很大程度上取决于要求,我们需要了解您的要求。 如果这是一个高stream量站点,并且在Web场中有负载平衡的服务器,则尽可能远离会话。 当然,可以在服务器场环境(会话服务器,分发caching服务器等)中以各种方式共享会话,但如果可以帮助的话,避免会话几乎总是会更快。
如果你的网站是一个单一的服务器,并不可能超过这个。 而你的stream量模式相对较低,那么会话可能是一个有用的select。 但是,您应该始终认识到会话是不可靠的存储,随时可能会消失。 如果应用程序池被回收,会话不见了。 如果未捕获exception冒泡到工作进程,则会话可能会消失。 如果IIS认为没有足够的内存,则无论configuration了任何超时值,您的会话都可能会消失。 你也不能总是得到一个会话结束的可靠通知,因为被终止的会话不会触发Session_End事件。
另一个问题是Session是序列化的。 换句话说,IIS会阻止多个线程同时写入会话,而且它通常会在线程正在运行的情况下通过locking会话来实现,如果它没有select不写可写会话locking的话。 这在某些情况下可能导致严重的问题,而在其他情况下则只能performance不佳。 如果您不打算在该方法中修改它,则可以通过用只读会话属性标记各种方法来缓解此问题。
最终,如果你select使用会话,那么尽量只用于短暂的小事情,如果不可能的话,那么在会话丢失的情况下build立一个“重新生成”数据的方式。 例如,使用购物车示例中的项目数量,可以编写一个方法,首先检查值是否存在,如果不存在,则将其从数据库中加载。 总是使用这种方法来访问variables,而不是直接从会话访问它…这样,如果会话丢失,它只会重新加载它。
然而,这么说…对于购物车中的物品数量,我通常更愿意使用这个信息的cookie,因为cookies无论如何都会传递给页面,而且这是一个小的离散数据单元。 通常更喜欢会话敏感的数据,你想防止用户能够改变..购物车中的项目数量根本不符合该规则。
什么时候
数据库被高度优化。 像购物车计数这样简单的值是数据库caching的一个很好的候选者,并且(希望)能够廉价地计算完全。 这可能不是问题。
但是,如果您排除了其他机制,那么小的,按用户的用户值是会话的可行候选人。
Cache
适用于站点范围内的值,或具有唯一键的用户特定值。 但是,跨多个Web服务器同步caching可能很困难。 进程外会话状态将保持同步,因为它存储在单个位置(数据库或状态服务器)中。
当然,有许多第三方caching替代scheme可以使各种选项保持同步。
无论计数暂时存储在哪里,我都认为购物车本身应该存储在数据库中,以便用户可以select稍后返回并继续停止。
性能
如果使用进程会话状态(例如,在负载平衡的环境中和/或使会话更持久),它将打到一个数据库或调用一个进程外的服务,但是这个调用是相对便宜的,除非你正在序列化大对象图表。
会话每个请求加载一次。 随后的读访问非常快。
写入会话可能会对性能造成不利影响,即使没有负载。 为什么? 大多数现代应用程序使用asynchronous调用,并且当多个asynchronous调用碰到读取/写入会话的HTTP处理程序(页面,控制器等)时,ASP.Net将locking会话以序列化访问。 为了避免这种情况,你可以用[SessionState( SessionStateBehavior.ReadOnly )]
来修饰你的控制器
devise
现在我已经成功地完成了这个任务,将值赋给一个从我的_layout视图中获取的Sessionvariables;
这似乎是混合问题,即让视图意识到底层存储机制。 从纯粹的angular度来看,我会在视图模型上设置这个值,或者至less把它放在ViewBag
。 从实际的angular度来看,以这种方式检索到的一个或两个值可能不会损害任何东西,但是要小心让它进一步增长。
我同时在Global.ascx应用程序开始部分看到了MVCfilter的使用,但是这对于在控制器级别设置的variables和静态variables可能不太合适。
静态variables具有完全合法的用途,但您必须彻底理解它们或者冒着严重的问题。
在ASP.Net中查看我有关静态variables的答案:
- aspx为c#静态variables提供了特殊的处理
- 静态字段与会话variables
不同的预期会议替代: –
当你在会话中保留某些东西时,它会打破ASP.NET MVC中的主要规则。 您可以使用这些选项作为会话的替代选项。
如果你的asp.net(MVC)会话在对象上进行拆箱拆箱,那么它会在服务器上造成一点负担。 试试这个想法
-
caching: – 在会话中存储List或类似大数据的东西更适合caching。 只要你希望它过期而不是用户会话,你就可以控制。
-
如果您的应用程序依赖于JSON / Ajax数据,那么您可以使用html5中提供的某种function(如WebSQL,IndexDB)。 它不会使用cookie,因此您可以在服务器上节省一些工作量。