在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文描述了一个自定义的会话状态存储提供者实现并示范一个范例提供者的实例。 ASP.NET 会话状态是为了简化 ASP.NET 应用程序在不同的源中存储用户会话数据而被设计的。默认时,会话状态的值和信息被存储在 ASP.NET 进程的内存中。作为选择,你可以把会话数据存储到一个状态服务器中,从而在一个单独的进程中保持会话数据并在 ASP.NET 应用程序被关闭或被重启的时候对其进行保留。另一个选择就是把会话数据存储到一个能够被多个 Web 服务器所共享的 SQL Server 数据库中。 你可以使用 ASP.NET 所提供的会话状态存储,或者你也可以实现自定义会话状态存储提供者。如下就是创建自定义的会话状态存储提供者时的两个主要原因。
你可以通过创建一个 SessionStateStoreProviderBase 的继承类来实现一个自定义的会话状态存储提供者。关于更多信息,请参考本文的稍后部分:[必需的类]。 会话状态模块在不同时间段内产生了请求的时候,SessionStateModule 类就会调用会话状态存储提供者来读取并写入会话数据。在请求刚开始的时候,SessionStateModule 通过调用 GetItemExclusive 方法从数据源中获取数据,或者在 EnableSessionState 页面参数被设置成 ReadOnly 的时候调用 GetItem 方法。在请求结束的时候,如果会话状态的值已经被更改,那么 SessionStateModule 就会调用 System.Web.SessionState.SessionStateStoreProviderBase.SetAndReleaseItemExclusive(System.Web.HttpContext,System.String,System.Web.SessionState.SessionStateStoreData,System.Object,System.Boolean) 方法把已经被更新的值写入到会话状态存储中。SessionStateModule 会调用 SessionStateStoreProviderBase 实现中的额外成员来初始化一个新的会话并在 System.Web.SessionState.HttpSessionState.Abandon 方法被调用的时候从数据存储中删除会话数据。SessionStateStoreProviderBase 类的每个成员在本文稍后的[必需的类]部分中被详细讨论。 SessionStateModule 能够检测它自已的 SessionID 属性值,胜于对对会话状态存储提供者的依赖。你可以通过创建一个继承自 ISessionIDManager 接口的类来实现自定义的 SessionIDModule。关于更多信息,请参考[ISessionIDManager 接口]中中所提供的备注。 SessionStateManager 将回复到 ASP.NET 进程的身份来访问任何已保护的资源(如某个数据库服务器)。你可以通过把 <sessionState> 配置元素的 useHostingIdentity 参数值设置成 false 的方式来指定 SessionStateModule 扮演由 IIS 所提供的身份。例如,如果你已经把 IIS 应用程序配置成使用被集成的 Windows 安全性并且你需要 ASP.NET 扮演由 IIS 所提供的并且与数据源连接所使用的身份相同的角色,然后在应用程序的 Web.config 文件的 <system.web> 配置段中指定 <identity impersonate="true" /> 并把 <sessionState> 配置元素的 useHostingIdentity 参数设置成 false。如果 useHostingIdentity 参数值为 true,那么在连接到数据源的时候,ASP.NET 将扮演处理器的身份,或者是存在于 <identity> 配置元素中的用户凭证。关于 ASP.NET 进程身份的更多信息,请参考:[配置 ASP.NET 的进程身份和 ASP.NET 的角色扮演]。 锁定会话存储数据ASP.NET 应用程序通过多线程来支持多个并发请求。使多个并发的请求尝试对相同会话信息的访问变得可能。考虑一个框架集的多个框架全部访问相同应用程序的情节,框架集中每个框架的单独请求可以在 Web 服务器的不同线程中并发地被执行。如果每个框架源中的 ASP.NET 页面都对会话状态变量进行访问,那么你就可以使用多个线程并发地访问会话存储。要避免会话存储以及意外的会话状态行为中的数据出现冲突,SessionStateModule 和 SessionStateStoreProviderBase 类包括了在 ASP.NET 页面的特定会话期间专门对会话存储项进行锁定的功能。注意在 EnableSessionState 参数被标记为 ReadOnly 的时候不会锁定会话存储项。但是,相同应用程序中的其他 ASP.NET 页面可能会改写会话存储,所以针对于只读会话数据的请求仍然需要等待被锁定的数据被释放才能被执行。 在请求刚开始调用 System.Web.SessionState.SessionStateStoreProviderBase.GetItemExclusive(System.Web.HttpContext,System.String,System.Boolean,System.TimeSpan,System.Object,System.Web.SessionState.SessionStateActionFlags) 方法的时候会对会话存储数据进行锁定。在请求被完成的时候,锁定就会在 System.Web.SessionState.SessionStateStoreProviderBase.SetAndReleaseItemExclusive(System.Web.HttpContext,System.String,System.Web.SessionState.SessionStateStoreData,System.Object,System.Boolean) 方法的调用期间被释放。 如果 SessionStateModule 在 GetItemExclusive 或者 GetItem 方法的调用期间遇到了被锁定的会话数据,那么它将每隔半秒时间就对会话数据进行一次重新请求,直到锁定被释放或者会话数据被锁定的时间期限超出了 ExecutionTimeout 属性值中的上限为止。如果执行时间已经超过了期限,那么 SessionStateModule 将会调用 System.Web.SessionState.SessionStateStoreProviderBase.ReleaseItemExclusive(System.Web.HttpContext,System.String,System.Object) 方法来释放会话存储数据并同时对该会话存储数据进行重新请求。 在一个单独的线程中为当前请求调用 SetAndReleaseItemExclusive 方法之前,被锁定的会话存储数据可能已经通过 ReleaseItemExclusive 方法的调用而被释放。这可能引起 SessionStateModule 被设置并且释放已经被释放并且被另一个会话所更改的会话状态存储数据。要避免这种情况的出现,SessionStateModule 为每个请求都包括了一个锁定标识符用来更改被锁定的会话存储数据。会话存储数据只能够在与数据存储中的锁定标识符与通过 SessionStateModule 所提供的锁定标识符相匹配的时候才能够被更改。 删除已过期的会话存储数据在为一个特定的会话而调用 Abandon 方法的时候,该会话的数据会使用 RemoveItem 方法从数据存储中被删除;否则数据将被保持在会话数据存储中并服务于该会话的未来请求。 删除已过期的会话数据的机制依赖于数据源的能力。如果数据源能够被配置成在每个会话超时的时候能删除已过期的会话数据,那么你就可以使用 SetItemExpireCallback 方法来引用 Session_OnEnd 的事件代表并在删除已过期的会话数据的时候对其进行触发。 ApplicationName要维护会话的应用范围,会话状态存储提供者应该为每个应用程序都分别存储唯一的会话信息。这允许多个 ASP.NET 应用程序在复制会话标识符时不出现冲突的情况之下使用相同的数据源。 因为会话状态存储提供者为每个应用程序分别存储了唯一的会话信息,所以你需要确保数据结构和查询中已经包括了对应用程序名称的更新。例如,如下所示的命令被用来从数据库中获取会话数据。 SELECT * FROM Sessions WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication' 作为选择,你还可以把会话标识符和与会话状态数据存储项相同的唯一标识符相同的应用程序名称进行联合存储。 必需的类要实现一个会话状态存储提供者,就需要创建一个由抽象类 SessionStateStoreProviderBase 所继承的类。而 SessionStateStoreProviderBase 则继承自 ProviderBase 抽象类,所以你还必须实现 ProviderBase 类的必需成员。下表列出了你必须为 ProviderBase 和 SessionStateStoreProviderBase 抽象类而实现的属性和方法并分别为它们提供了描述信息。要查看每个成员的实现,请参考:[会话状态存储提供者的范例]。 必需的 ProviderBase 类成员
必需的 SessionStateStoreProvider 类成员
范例提供者要查看一个使用 System.Data.Odbc 命名空间中的类并在 Access 数据库中管理会话信息自定义会话状态存储提供者的实现范例,请参考:[会话状态存储提供者的范例]。 |
请发表评论