我正在寻找关于如何在ASP.NET MVC应用程序中使用Session的想法?特别是在使用masterpages和tryin只是将数据传输到母版页而不绕过控制器时。这个问题始于我提出了许多小问题,但后来我设法把它塑造成一个解决方案,但我还没有实现,但有一个方面是可行的。非常感谢任何反馈。
我建议的解决方案,即“我要实施的内容,除非有人说停止!”
我有继承自ModelBase的模型类 - 它包含母版页所需的信息(每页只有一个视图),用于显示在标头或页脚中的某些内容以及基于谁的配置驱动设置登录。
我的最佳解决方案如下所示 - 此处显示的是“产品页面”:
假设:我在某些时候已经在会话中粘贴了某些数据 - 例如,可能是
partnerId
通过网关页面或currentLoggedInUserEmail
属性或一个完全被炸毁的物体。我有一个
ModelBase
类,每个模型 - 例如ProductModel
都继承了我有一个
MySiteControllerBase
类(继承自Controller) - 由ProductController
子类化。在我
ProductController
的操作方法中,我使用'new ProductModel()'
为产品视图创建模型。此模型类本身对会话或如何填充ModelBase
一无所知。它本质上甚至不知道ModelBase
- 它只是从它继承而来。我的链式构造函数什么都不做(因为我不想传递它Session
)。我在
View(...)
中覆盖了带有模型参数的所有重载的MySiteControllerBase
。我检查该参数是否为ModelBase
类型,如果是,则填充partnerid
和currentLoggedInuserEmail
等属性。幸运的是,因为我在一个继承自Controller
的类中,所以我可以直接访问Session
,所以我可以将它们直接从那里拉出来。
此方法意味着ModelBase
上的属性仅由我'return View(model)'
自动填充。但是,如果ProductModel
的模型需要访问ModelBase
上定义的任何内容,则会出现明显的问题。它将变为null,因为它尚未填充。
可以通过将Session
传递给new ProductModel(session)
来解决此问题,而new ModelBase(session)
会将构建器链传递给ProductController
。我真的不喜欢那个解决方案,但因为我喜欢将模型看作一个非常愚蠢的数据结构,根本不应该知道任何外部数据结构。另一个解决方案可能就是将它放在一边,如果我发现ModelBase
需要消耗MySiteControllerBase.UpdateModelBase(productModel, session)
中定义的任何内容,我只需要创建一个方法ProductController
以在{{1}中明确填充它}}。我希望那清楚!
我想到的其他问题是:
答案 0 :(得分:1)
对于单元测试,您需要一个假的HttpContext对象(从HttpContextBase扩展)和一个假的会话对象(从SessionStateBase扩展)。或者你可以做我们做的事情,并使用Phil Haacks HttpSimulator。这不是一个完美的解决方案,但有很多紧密耦合的对象,当你用asp做任何事情时都会连接起来,你真的找不到任何特别优雅的东西。我们发现我们不断碰到它,以至于抓住这些类并将它们粘贴在帮助程序库中是值得的。
Cookie是按域工作的,因此没有任何问题。您始终可以将会话配置为进程内和无cookie。
一般情况下,您在会话中保留的内容非常稀少。但这也适用于Webforms。
答案 1 :(得分:1)
虽然原则上在ASP.NET MVC应用程序中使用Session没有任何错误(好吧,至少没有比在其他ASP.NET应用程序中使用它更错误了),我倾向于认为它应该是当其他事情不起作用时,最后的手段。
虽然你的问题通常写得非常好,但你不会详细介绍你打算在Session中存储的内容。我在你的问题中找到的两个例子是:
如果您正在使用表单身份验证,则用户的电子邮件地址已经可用,并且可以添加到尚未支持它的其他ASP.NET成员资格提供程序中。目前尚不清楚合作伙伴实际上是什么,但我怀疑会议是唯一存储它的地方。
另一方面,完全有可能你需要存储你没有告诉我们的东西,哪些东西真的只适合会话。
因此,在您走这条路之前,请确保其他解决方案尚不适用于您需要存储的数据。