在ashx和静态文件中使用Session

  在ashx页面中如果想使用可读可写的Session,必须要实现一个接口“IRequiresSessionState”,在这个接口中没有定义任何方法,这样的接口被称为“标识接口”。

public interface IRequiresSessionState {
}

  

  在IIS中,对后台的页面请求都会经过管道。如果该请求指向的是物理文件,并且该请求没有被路由,那么会通过地址去获得一个匹配的继承自HttpHandler的对象,获得到的对象会被保存在HttpContext的Handler属性中,以供请求的后续步骤使用。

 public IHttpHandler Handler {
            get { return _handler;}
            set {
                _handler = value;
                _requiresSessionStateFromHandler = false;
                _readOnlySessionStateFromHandler = false;
                InAspCompatMode = false;
                if (_handler != null) {
                    if (_handler is IRequiresSessionState) {
                        _requiresSessionStateFromHandler = true;
                    }
                    if (_handler is IReadOnlySessionState) {
                        _readOnlySessionStateFromHandler = true;
                    }
                    Page page = _handler as Page;
                    if (page != null && page.IsInAspCompatMode) {
                        InAspCompatMode = true;
                    }
                }
            }
        }

  上面贴出的代码就是HttpContext的Handler属性的get和set访问器,可以看到在set访问器中,通过判断当前的Handler对象是否继承自标识接口而为HttpContext的两个字段赋值。在后面的附加Session状态的方法中就会使用HttpContext的一个属性RequiresSessionState。

internal bool RequiresSessionState {
            get {
                switch (SessionStateBehavior) {
                    case SessionStateBehavior.Required:
                    case SessionStateBehavior.ReadOnly:
                        return true;
                    case SessionStateBehavior.Disabled:
                        return false;
                    case SessionStateBehavior.Default:
                    default:
                        return _requiresSessionStateFromHandler;
                }
            }
        }

  这个属性中默认情况下会使用上面提到的字段_requiresSessionStateFromHandler。

     SessionStateBehavior这个属性表示的是会话状态是被禁用、读写、只读,可以通过HttpContext的SetSessionStateBehavior对该属性进行赋值。

  如果遇到需要在静态文件中也使用session的情况,那么必须先将runAllManagedModulesForAllRequests属性设置true,再在管道事件中的AcquireRequestState事件之前,手动设置会话状态行为,最后再配置会话状态httpmodule。

1、配置文件,配置所有静态文件都走管道
<
configuration> ... <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <remove name="Session"/> <add name="Session" type="System.Web.SessionState.SessionStateModule"/> </modules> </system.webServer> ... </configuration>
2、管道事件,设置静态文件的会话状态行为
protected void Application_PostMapRequestHandler(object sender, EventArgs e)
{
    var app = (HttpApplication)sender;
    if (是需要校验会话状态的静态文件)
    {
        app.Context.SetSessionStateBehavior(SessionStateBehavior.Required);
    }
}
3、配置文件,配置会话状态的module为SessionStateModule,这样就会使用到上面设置到SessionStateBehavior.Required
<
configuration> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <remove name="Session"/> <add name="Session" type="System.Web.SessionState.SessionStateModule"/> </modules> </system.webServer> </configuration>

 

posted @ 2015-03-31 10:14  守望雲影  阅读(407)  评论(0编辑  收藏  举报