避免在ASP.NET MVC中使用会话状态是一种好习惯吗?如果是,为什么以及如何?

时间:2011-03-07 14:39:45

标签: asp.net asp.net-mvc

它没有明确地写在某处,但在阅读了几篇关于ASP.NET MVC的博客后我感觉如此。只是好奇并想到这里问。

更新:
我不是在询问服务器上的内存/存储/ RAM问题。对于他们来说,存在一个解决方案来存储会话进程。我知道。我很好奇,有没有我们不得不在WebForms中使用Session的情况,但我们现在可以在MVC中避免使用MVC提供的结构良好的方式吗?

8 个答案:

答案 0 :(得分:41)

在ASP.NET Web窗体中,如果不使用会话,在不同页面之间传递信息从未如此简单。由于以回发为中心的模型,服务器上的信息作为事件的一部分可用,但通常在错误的页面中显示结果,在必要的页面之间传递信息。

这往往导致过度使用会话,在会话中填充“当前”变量,旨在指示当前与之交互的对象是什么。这种过度使用反过来使应用程序非常依赖于状态,并且更难以确定预期的行为(“这个变量是否已填充?”“我还有当前的订单ID吗?”)。

MVC的结构是,您的网站是一个信息逻辑模型的视图。它通过使用简单的控制器响应具有作为HTTP请求的一部分传递的密钥信息的操作来鼓励进行无状态操作。

由于这些属性,不再需要会话来执行MVC中的基本任务,并且在以前看起来完全有效的选择之前变得不合适。


从根本上说,会话会污染HTTP 。它使请求(通常包含它们自己的状态)取决于接收服务器的内部状态。这就是为什么它被视为一种邪恶(虽然通常是一种实用和必要的)。

答案 1 :(得分:14)

甚至在MVC之前就避免了会话,因为在服务器上为连接到您的应用程序的每个用户持有的信息(与缓存不同)在不使用时不会自动删除。

另外,为了帮助您避免使用会话,ASP.NET拥有viewstate,这实际上是您的webforms中一个巨大的隐藏字段,每次回发都会发布POST。由于各种原因,这也太笨拙了,而且随着MVC而被淘汰。

因此,即使在MVC之前,会话实际上并不是非常推荐的。原因主要是可扩展性。您坚持的状态越少,您的网站就越具有可扩展性。 如果您不关心可伸缩性(我知道您可能正在为200个用户开发内部网应用程序),或者如果您通过各种方式持有的信息很少,请使用会话。在其他情况下,使用会话是完全合适的:使用会话状态的典型场景是电子商务网站中的购物车(信息本身就是每个用户每个会话,并且实际上只有一部分用户已经填充)。

至于替代方案,没有直接的替代会话。根据您尝试的操作,您可以使用缓存或Cookie。在这方面,MVC没有带来任何特别新的东西,AFAIK。

答案 2 :(得分:6)

避免为您使用会话状态意味着什么?您是否需要在请求中方便地存储少量用户数据?如果是这样,你会怎么做呢?

我不确定会话状态的替代方案是什么。使用会话状态,开箱即用,在ASP.NET中更适合滚动自己的替代方案,尤其是从安全角度来看。

答案 3 :(得分:5)

使用TempData代替HttpSessionStateTempData是Mvc的Session状态包装器。

答案 4 :(得分:2)

添加到以前的答案

会话在现代应用程序方面通常是邪恶的,现代应用程序主要适用于以云为中心的应用程序,但在很大程度上取决于我们存储它们的位置。

无论ASP.NET WebForms还是ASP.NET MVC,通常使用会话,我们都会想到一个购物车,其中包含已填充或已删除的购物车,这些购物车在整个会话维护过程中都会得到维护。所以这是一种简单而廉价的做事方式,通常会话就在

  1. 是InProc
  2. 的StateServer
  3. SQLServer的
  4. 现在使用分布式缓存more details
  5. 出生时的HTTP是无状态的,所以当我们想要横向扩展应用程序时,我们将节点添加到Web层或其他层,所以现在问题是哪个节点将服务于当前用户的请求?它在很大程度上取决于负载均衡器,它具有不同的平衡模式。

    因此,多个节点可以根据负载均衡器为同一用户提供请求,但是我们可以使用web层中的粘性会话覆盖,这将确保当前用户将使用相同的节点,这在扩展应用程序时失败,经典示例考虑我们有在每2个节点上有1,000个活动会话,现在我们再添加一个节点,我们通常期望3个节点共享接近相同数量的会话但是因为那些1000个必须在特定节点中处于活动状态而导致我们使用粘性会话,缩放需要时间直到这些会议已经结清。

    如果我们想要扩展或反向缩放应用程序又是什么?或者一个或多个服务器出现故障,如果我们在InProc或StateServer上保持会话,甚至当Web层节点为同一用户切换时,整个会话数据将会丢失,而如果我们在SQLServer上存储它很好但通常很慢,所以答案在这里似乎是分布式缓存,速度快,可以变得可靠。

答案 5 :(得分:1)

这实际上取决于您在会话状态中维护的数据量。根据经验,我尝试在这里和那里使用它来做几个字符串而不是更多。例如,对于大型表单,我可能会将引用ID存储到该会话,然后根据该ID将所有需要的数据存储在SQL临时表中。这有点痛苦,但会话状态并不意味着用于存储大量信息。

答案 6 :(得分:1)

会话过期通常与用户的意图不符(例如,如果IIS回收,则会丢失您的inproc会话状态)。我认为唯一可能有用的是用户数据缓存,而不是真实的权威来源(最有可能是DB)。

答案 7 :(得分:0)

从ASP.net Web Forms到ASP.net MVC,会话管理总是充满挑战。但是,MVC鼓励将其视为无状态,因为您已经从基于 REST 的Web API中受益。我们以前在Session中存储的大部分内容都是通过使用MVC + Web API组合完成的。