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

它没有明确写在什么地方,但是在阅读ASP.NET MVC上的一些博客之后,我感觉如此。 只是好奇,想到这里问。

更新:
我不问在服务器上的内存/存储/内存问题。 对他们来说,有一个解决scheme可以将会话保存为进程外。 我知道。 我很好奇,有什么情况下我们不得不在WebForms中使用Session,但是现在我们可以在MVC中利用MVC提供的很好的结构化方式来避免它吗?

在ASP.NET Web窗体中,如果不使用会话,在不同页面之间传递信息就不是那么容易了。 由于以回传为中心的模型,服务器上的信息作为事件的一部分是可用的,但是通常在显示结果的错误页面中,必须在页面之间传递信息。

这往往会导致会话过度使用,在会话中填充“当前”variables旨在指示当前正在与之交互的对象是什么。 这反过来又使得应用程序非常依赖状态,而且很难确定预期的行为(“这个variables是否被填充?”“我有当前的订单ID吗?”)。

MVC是围绕着这样的观念构build的,即你的网站是一个信息逻辑模型的视图。 它鼓励通过使用简单的控制器响应具有作为HTTP请求的一部分传递的关键信息的动作的无状态操作。

由于这些属性,会话不再需要在MVC中执行基本任务,并且在之前似乎是完全有效的select的情况下变得不合适。


会话基本上会污染HTTP 。 它根据接收服务器的内部状态发出请求(通常包含它们自己的状态)。 这就是为什么它被视为邪恶的东西(虽然通常是一个实际的和必要的)。

甚至在MVC之前,会话就被避免了,因为它是连接到你的应用程序的每个用户在服务器上持久化的信息,并且(不像caching)在不使用时不会被自动擦除。

此外,为了帮助您避免使用会话,ASP.NET有viewstate,这实际上是每个回发中发布的web表单中的一个巨大的隐藏字段。 这也是由于各种原因太笨拙,并与MVC下降。

所以会议实际上是甚至在MVC之前不被推荐的东西。 原因主要是可扩展性。 您持续的状态越less,您的网站的可扩展性就越高。 如果你不关心可伸缩性(因为我知道你可能正在为200个用户开发一个内部网应用程序),或者如果你有很less的信息要坚持使用会话。 在其他情况下,使用会话是完全合适的:使用会话状态的典型场景是电子商务网站中的购物车(信息本质上是每个用户每个会话,只有一部分用户实际已经填充)。

至于替代scheme,没有一个直接的替代会议。 根据你想要做什么,你可能能够使用caching或cookies。 在这方面,MVC并没有带来任何特别的新东西,AFAIK。

为了避免使用会话状态,这意味着什么? 你是否需要方便地存储less量的用户数据请求? 如果是的话,你还会怎么做?

我不确定会议状态的替代scheme是什么。 使用会话状态(Session State),开箱即用,在ASP.NET中更适合于自己的select,特别是从安全的angular度来看。

使用TempData而不是HttpSessionStateTempData是Mvc会话状态的包装。

添加到以前的答案

会话在现代应用程序中通常是邪恶的,现代应用程序主要适用于以云为中心的应用程序,但是非常依赖于我们存储它们的位置。

无论ASP.NET WebForms还是ASP.NET MVC(通常使用会话),我们都可以设想一个购物车,其中包含已装满或已移除的购物车,并在维护实际会话的过程中进行维护。 所以这是简单而便宜的做事方式,通常是会话所在

  1. 是InProc
  2. 的StateServer
  3. SQLServer的
  4. 现在分布式caching更多的细节

由于出生时的HTTP是无状态的,所以当我们想要横向扩展应用程序时,我们将节点添加到Web层或其他层,所以现在的问题是哪个节点将服务于当前用户的请求? 这很大程度上取决于具有不同平衡方式的负载均衡器。

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

如果我们要扩大规模或扭转规模化应用,又该怎么办? 或者一个或多个服务器断开,如果我们在InProc或StateServer上保持会话,甚至当Web层节点为同一个用户切换时,整个会话数据将会丢失,而如果我们在SQLServer上存储它很好但通常很慢,所以这里的答案似乎是分布式caching,这是快速的,可以做到可靠。

这实际上取决于您在会话状态中维护多less数据。 作为一个经验法则,我尝试在这里和那里使用它几个string,没有更多。 例如,对于大型表单,我可能会将参考ID存储到该会话中,然后根据该ID将所有需要的数据存储在SQL临时表中。 这是一种痛苦,但会话状态并不意味着被用来存储大量的信息。

会话到期通常不符合用户的意图(例如,如果IIS回收,您的inproc会话状态丢失)。 唯一我认为可能有用的是用户数据caching,而不是真实的权威来源(最可能应该是数据库)。

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