【问题标题】:How should I integrate session state into an ASP.NET MVC application?我应该如何将会话状态集成到 ASP.NET MVC 应用程序中?
【发布时间】:2010-10-04 04:10:02
【问题描述】:

我正在寻找有关如何在 ASP.NET MVC 应用程序中使用 Session 的想法?尤其是在使用母版页并试图在不绕过控制器的情况下将数据获取到母版页时。这个问题一开始是我问了很多小问题,但后来我设法将它塑造成一个我还没有实施但有点可行的解决方案。如有任何反馈,将不胜感激。


我提出的解决方案又名“除非有人说停止,否则我将要实施的方案!”

我的模型类继承自 ModelBase——它包含母版页所需的信息(每页只有一个视图),用于显示在标头或页脚中的某些内容以及基于谁的配置驱动设置已登录。

我的最佳解决方案如下 - 此处显示为“产品页面”:

假设:我在某些时候已经将某些数据卡在会话中 - 例如可能是通过网关页面进入的 partnerId,或者 currentLoggedInUserEmail 属性或完全成熟的对象.

我有一个 ModelBase 类,每个模型(例如 ProductModel)都从该类继承

我有一个 MySiteControllerBase 类(从 Controller 继承) - 它是 ProductController 的子类。

ProductController 的操作方法中,我使用'new ProductModel()' 为产品视图创建模型。这个模型类本身对会话或如何填充ModelBase 一无所知。它本质上甚至不知道ModelBase——它只是继承自它。我的链式构造函数什么都不做(因为我不想传递它Session)。

对于所有采用模型参数的重载,我在 MySiteControllerBase 中覆盖 View(...)。我检查该参数是否为ModelBase 类型,如果是,我填充诸如partneridcurrentLoggedInuserEmail 之类的属性。幸运的是,因为我在一个继承自 Controller 的类中,所以我可以直接访问 Session,所以我可以直接将它们从那里拉出来。

这种方法意味着ModelBase 上的属性仅由我执行'return View(model)' 自动填充。但是,如果ProductModel 的模型需要访问ModelBase 上定义的任何内容,则会出现一个明显的问题。它将为 null,因为它尚未填充。

这个问题可以通过将Session 传递给new ProductModel(session) 来解决,而new ProductModel(session) 又会将它通过构造函数链传递给new ModelBase(session)。我真的喜欢那个解决方案,因为我喜欢将模型视为一个非常愚蠢的数据结构,根本不应该知道任何外部数据结构。另一种解决方案可能是直接使用它,如果我发现ProductController 需要消耗ModelBase 中定义的任何内容,我只需创建一个方法MySiteControllerBase.UpdateModelBase(productModel, session) 以在ProductController 中显式填充它。我希望这很清楚!

想到的其他问题是:

  • 单元测试呢? MVC 中的会话状态是否有任何抽象,或者我应该自己构建?我在源代码中搜索了“会话”,但没有任何结果!
  • 会话跟踪如何与 MVC 中的 /REST/FUL/URLS 一起工作?我需要了解有关关闭 cookie 的任何问题吗?
  • 我是否应该以不同于以往的方式来看待会话?

【问题讨论】:

    标签: asp.net-mvc session master-pages


    【解决方案1】:

    虽然原则上在 ASP.NET MVC 应用程序中使用 Session 并没有什么问题(好吧,至少没有什么比在其他 ASP.NET 应用程序中使用它更错误的了......),我倾向于认为它应该是最后的手段,当其他事情不起作用时。

    尽管您的问题通常写得非常好,但您并没有详细说明您建议在 Session 中存储的内容。我在你的问题中找到的两个例子是:

    • 当前用户电子邮件
    • 合作伙伴ID

    如果您正在使用表单身份验证,用户的电子邮件地址已经可以使用,并且可以添加到其他尚不支持它的 ASP.NET 成员资格提供程序。不清楚 partnerid 实际上是什么,但我怀疑 Session 是唯一可能存储它的地方。

    另一方面,您完全有可能需要存储您没有告诉我们的内容,而哪些内容实际上只适合会话。

    因此,在您在这条道路上走得太远之前,请确保其他解决方案尚不适用于您需要存储的数据。

    【讨论】:

    • 老实说我还不完全了解——我只是想成为 MVC 方面的专家并弄清楚一切。我们的网站将有一个带有超酷 AJAX 界面的“迷你”购物车,然后将其状态传递给我们“不那么令人兴奋”购买的购物车。所以我需要一个“购物车”
    • 我的主要目标是 1) 确保没有人编写的 MVC 会话中没有好的抽象(以便更容易测试)和 2) 确保我最有效地使用和处理MVC 框架内的会话
    • @craig 你正在创建什么样的应用程序,你不需要会话?
    • 现在我正在构建一个安全的 Web 应用程序来为各种不同的任务输入时间。但我正在使用的唯一“会话”是 TempData。 (ASP.NET MVC 将这个临时存储在会话中。) 把这个问题抛在脑后,什么样的数据只能存储在会话中?
    【解决方案2】:

    至于单元测试,您将需要一个假 HttpContext 对象(从 HttpContextBase 扩展)和一个假会话对象(从 SessionStateBase 扩展)。或者您可以按照我们的做法使用 Phil Haacks HttpSimulator。这不是一个完美的解决方案,但是当您使用 asp 做任何事情时,有很多紧密耦合的对象会连接在一起,以至于您永远不会真正发现任何特别优雅的东西。我们发现我们经常碰到它,所以值得抓住这些类并将它们放在帮助库中。

    Cookie 是按域工作的,所以这方面确实没有任何问题。您始终可以将会话配置为进程内且无 cookie。

    一般来说,在会话中保留的内容要非常少。但这也适用于 Webforms。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      • 2020-02-24
      • 2013-11-03
      • 2011-04-23
      • 1970-01-01
      相关资源
      最近更新 更多