如何覆盖会话属性?

Posted

技术标签:

【中文标题】如何覆盖会话属性?【英文标题】:How to overwrite the session property? 【发布时间】:2012-03-17 16:07:59 【问题描述】:

问题:

通常,访问会话对象的方式如下:

Session["foo"] = "bar";

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

为了使用我的会话访问权限,我必须像这样通过我的班级访问会话

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

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

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

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

SessionTimeout 上的那些 NULL-Reference 异常 YSOD 非常令人不安。 如果可能的话,一个适用于经典 ASP.NET 网络表单以及 MVC 的解决方案。

【问题讨论】:

它的覆盖,也,不明白你的问题的重点。 嗯,顺便说一句,这就像 .NET 的弯路/函数拦截的理想应用。我可以使用鼹鼠框架。 你真的需要这个吗?将您的辅助方法作为扩展方法添加到 HttpSession 类怎么样? 您可以覆盖 Session 属性,但不能用您自己的方法替换它,因为它没有相同的签名:您的方法是通用的。 @Darin Dimitro:是的,但我总是可以围绕它写一个包装器 SessionAccess.Set("foo", "bar"); 【参考方案1】:

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

    创建另一个提供索引器属性的包装器,以便您可以轻松地将 Session["key"] = "name" 等调用替换为您的包装器属性; 您需要从一个通用的基本页面类(它本身从 System.Web.UI.Page 间接继承)继承所有页面(即代码隐藏类)。如果您已经有这样的基本页面,那么您的情况确实很好。从本身继承自 System.Web.UI.Page 的内部基类继承您的公共页面基类。 在公共页面库中,添加一个新的 Session 属性,该属性将返回您在 #1 中创建的包装器对象。如果您有很多 UserControl(和自定义控件),则必须对它们进行类似的技巧。这将使您免于替换大部分 Session["key"] = "name" 类型的调用。 最后,覆盖内部基页类中的 Session 属性以添加调试断言。您可以选择返回 null 但这会破坏生产使用。调试断言对于查找将从 #3 中转义的会话使用情况要好得多。

如前所述,这不是一个完整的解决方案,因为仍然可以通过 HttpContext 访问会话状态。但它应该使遗留代码迁移到您的会话访问器对象更容易。

【讨论】:

然后我必须替换所有的 ascx 和 ascx 实例,如果它在一个类中使用,它仍然会崩溃。我更多的是寻找类似的东西:***.com/questions/8487801/… @Quandary,不幸的是,HttpSessionState 是一个密封类,因此,不能将任何自定义会话状态实现放在 http 上下文中。是的 - 它可以被嘲笑,但嘲笑可能代价高昂! 好吧,坏主意。鼹鼠框架是一块废话。我放弃。我的问题的答案是:不可能。

以上是关于如何覆盖会话属性?的主要内容,如果未能解决你的问题,请参考以下文章

2.2 ABP会话

如何拦截会话结束并获取属性?

会话覆盖实现

Meteor 模板状态与全局会话

如何在 laravel 中进行会话?

如何设置 Spring 会话范围 bean 的属性名称?