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

Ism*_*ilS 41 asp.net asp.net-mvc

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

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

Pau*_*ner 42

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

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

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

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


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

  • 我认为在会话中保留"当前"变量的部分原因是为了避免向数据库进行往返以重新获取数据.但就像你说的那样,有时它被过度使用(并且不必要地). (5认同)
  • 安全性是否是否使用会话变量的考虑因素; 他们总是在服务器上,你不必担心他们在传输中被截获.但这并不是说它们是唯一的解决方案,因为有许多方法可以保护部分或全部HTTP请求,这些技术是您要为HTTP请求的其他元素考虑的. (3认同)
  • 用户的ID是上下文信息.如果您不想使用会话,则可以将其作为HTTP请求的一部分提供(例如,自定义标头).但是,我要说用户上下文信息适合存储在会话中; 如果您的会话过期,用户必须再次登录. (2认同)
  • 登录cookie提供User.Identity,并且它们是加密的.使用Identity 2.0,我知道您甚至可以控制它们的加密方式,您肯定会在网络服务器场中这样做.客户端会在每次请求时发送Cookie,因此您应该始终拥有这些Cookie.无需使用会话.无状态意味着客户端提供处理请求所需的所有信息.这允许服务器场中的任何服务器独立处理它并返回有效的响应. (2认同)

Pao*_*lla 15

甚至在MVC之前就避免了会话,因为对于连接到您的应用程序的每个用户而言,它在服务器上持久保存的信息(与缓存不同)在不使用时不会自动擦除.

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

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

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

  • @LordCover抱歉,重新阅读我的回答我太教条了.在任何情况下都不应该避免会话,并且很可能在使用会话时完全合适.只是您可以设计的Web应用程序越多,以避免维护状态,它就越具有可扩展性.也就是说,替代方案取决于您尝试保留的数据类型以及原因. (2认同)

Jos*_*rce 6

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

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


sma*_*man 6

TempData而不是HttpSessionState. TempData是Mvc的Session状态包装器.