如何覆盖会话属性?

时间:2012-02-28 06:54:12

标签: c# asp.net asp.net-mvc asp.net-mvc-3 session

问题:

通常,人们会像这样访问会话对象:

Session["foo"] = "bar";

我已经编写了一个包装器,它是通用的,它会检查会话是否已过期,如果是这样,则抛出SessionExpiredException。

为了使用我的会话访问权限,我必须像我这样访问我的课程

WebApplications.SessionAccess.Set<string>("foo", "bar");

现在,显然,尽管存在类SessionAccess,仍然可以通过普通会话对象访问会话。这是不可取的,另外,我想稍后将它包含在一个更大的旧项目中,该项目是使用普通的Session编写的,这意味着我必须用my替换所有对session的调用(低数千的数字)包装

有没有办法可以覆盖System.Web.HttpSessionStateBase.Controller.Session - 我自己的属性?

问题是,如果没有在web.config中定义自定义会话处理程序,因为有时已经有一个用于将数据库用于会话(一个仍然可以初始化Global.asax中的模块)。

SessionTimeout上的那些NULL-Reference异常YSOD是非常令人不安的 如果可能的话,这个解决方案适用于传统的ASP.NET Web表单以及MVC。

1 个答案:

答案 0 :(得分:0)

我认为不会有任何完全可靠的解决方案,但很少有技巧可以让您的生活更轻松。

  1. 创建另一个提供索引器属性的包装器,以便您可以轻松地将诸如Session["key"] = "name"之类的调用替换为包装器属性;
  2. 您需要从公共基页类继承所有页面(即代码隐藏类)(它本身已从System.Web.UI.Page继承间接)。如果您已经有这样的基页,那么您的情况确实很好。从内部基类继承您的公共页基类,该基类本身继承自System.Web.UI.Page。
  3. 在公共页面基础中,添加一个新的Session属性,该属性将返回在#1中创建的包装器对象。如果您有很多这样的技巧,必须为UserControl(和自定义控件)执行类似的操作。这样可以避免替换大多数Session["key"] = "name"种电话。
  4. 最后,覆盖内部基页类中的Session属性以添加调试断言。您可以选择返回null,但这会破坏生产使用。调试断言要好于查找将从#3中转义的会话使用情况。
  5. 如上所述,这不是一个完全证明的解决方案,因为仍然可以通过HttpContext访问会话状态。但它应该使遗留代码迁移到会话访问者对象更容易。