虽然来晚了,但我刚刚发现一个东西。
@Phillipe Leybaert 和 @CSharpAtl 都是错误的。 HttpApplication
的Session
属性表现出与HttpContext.Current.Session
属性不同的行为。如果有可用的HttpSessionState
实例,则两者都将返回对该实例的引用。在当前请求中没有HttpSessionState
实例时,它们的行为不同。
并非所有的HttpHandler
都提供会话状态。要提供会话状态,HttpHandler
必须实现[一种或两种?]标记接口IRequiresSessionState
或IReadOnlySessionState
。
如果没有会话可用,HttpContext.Current.Session
只会返回null
。
HttpApplication
中的Session
属性实现会抛出一个带有消息“Session state is not available in this context.”的HttpException
而不是返回null
引用。
一些未实现会话的HttpHandler
示例是通常为静态资源(如图像和CSS文件)提供默认处理程序。在此类情况下(例如,在global.asax
事件处理程序中),对HttpApplication
的Session
属性的任何引用都将导致抛出HttpException
。
不用说,如果您没有预期,意外的HttpException
会让人无所适从。
HttpApplication
类的Session
属性实现如下(来自Reflector):
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public HttpSessionState Session
{
get
{
HttpSessionState session = null;
if (this._session != null)
{
session = this._session;
}
else if (this._context != null)
{
session = this._context.Session;
}
if (session == null)
{
throw new HttpException(SR.GetString("Session_not_available"));
}
return session;
}
}
没有区别。
Page.Session的getter方法返回上下文会话。
没有什么特别的。 Session
只是指向 HttpContext.Current.Session
。
内部来说,Page.Session只指向HttpContext.Current.Session,但是根据调用的来源,仍然有两个不同之处。
只有从System.Web.UI.Page继承的类中才能访问Page.Session,当从WebMethod中访问时,它将抛出HttpException。
而HttpContext.Current.Session可以在任何地方访问,只要你在Web应用程序的上下文中运行即可。
另一个重要的区别是你可以访问Page.Session但无法访问HttpContext.Current.Session:
如果你的页面(从System.Web.UI.Page继承)中有一个名为GetData的方法,在其他页面方法中并发执行,GetData方法可以访问Page.Seession,但你不能访问HttpContext.Current.Session。
这是因为GetData已经从不同的线程调用,所以HttpContext.Current为空,HttpContext.Current.Session会抛出空引用异常,但Page.Session仍然附加在页面对象上,因此页面方法GetData可以访问Page.Session。