Global.asax中各事件应注意那些操作以及有关的常见问题看法

来源:互联网 发布:Ubuntu是否自带gcc 编辑:程序博客网 时间:2024/05/16 04:46

  

  做计数器、统计在线人数、页请求处理、登录控制等等,可能就要考虑Global.ascx的一些应用。近来看到很多网友在此问题上提问,整理自己遇到的一些问题,望给初学者一个帮助。 

       如果对Global.asax里的执行顺序不了解,先阅读这篇文章: 

http://reeezak.cnblogs.com/archive/2005/10/09/251201.html

   前提说明:

Application_Start请求 ASP.NET 应用程序中第一个资源(如页)时调用。在应用程序的生命周期期间仅调用一次 Application_Start 方法。可以使用此方法执行启动任务,如将数据加载到缓存中以及初始化静态值。在应用程序启动期间应仅设置静态数据。由于实例数据仅可由创建的 HttpApplication 类的第一个实例使用,所以请勿设置任何实例数据。比如在计数器当中,设置一下计数的初始值。或者在此写个应用程序级的判断,条件正确就停止此应用程序,呵呵,如果有这种需求。

Application_End在卸载应用程序之前对每个应用程序生命周期调用一次。

Session_Start如果请求开始一个新会话,Session_Start 子例程会在请求开始时运行。如果请求不包含 SessionID 值或请求所包含的 SessionID 属性引用一个已过期的会话,则会开始一个新会话。

Session_End Abandon 方法已被调用或会话已过期时运行。如果超过了某一会话 Timeout 属性指定的分钟数并且在此期间内没有请求该会话,则该会话过期。注意:只有会话状态属性 Mode 设置为 InProc(默认值)。

Application_BeginRequest在收到Request时第一个触发的事件。

Application_EndRequest每次请求结束时会引发的事件。注意:每次请求都会执行此事件,例如,如果有两个模块处理  Application_BeginRequest 事件,第一个模块引发一个异常,则不会为第二个模块调用 Application_BeginRequest 事件。但是,会始终调用 Application_EndRequest 方法使应用程序清理资源。

Application_Error:所有没有处理的错误都会导致这个方法的执行。

HttpModuleASP.NET 应用程序生命周期可通过 IHttpModule 类进行扩展。ASP.NET 包含若干实现 IHttpModule 的类,如 SessionStateModule 类。您还可以自行创建实现 IHttpModule 的类。这里所说的就是自己扩展的HttpModule了。

问题点:

1.Application_Start为什么不能使用Response

答:此时在Application_Start并不能响应页面,从上面的说明中可看出,还没有执行到Request_BeginQequest.可用Context.Response来解决此问题。

2.有人问为什么Application_Start我在没有重启IIS(或其它应用服务器)时,他执行过N次?

答:在确定IIS(或其它应用服务器)没重启时,看看是否动态更改了Web.config,而导致你的应该程序周期结束。

还有人问Application_Start只在周期开始执行一次,那可不可以在此做个判断,停止整个应用程序周期?

答:当然可以,前提是你有这种需求。搞笑版。

3.做个登录统计吧

         public void Application_Start(Object sender, EventArgs e)       

         {

              Application["UsersOnline"] = 0;

         }

         public void Session_Start(Object sender, EventArgs e)

         {

              Application.Lock();

              Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;

              Application.UnLock();

         }

         public void Session_End(Object sender, EventArgs e)

         {

              Application.Lock();

              Application["UsersOnline"] = (int)Application["UsersOnline"] - 1;

              Application.UnLock();

                   }

在这问题就出来了:

为什么我关闭了浏览器Session_End并没有结束?

答:上面说到Session_End在这两种情况下结束:在 Abandon 方法已被调用或会话已过期时运行。如果超过了某一会话 Timeout 属性指定的分钟数并且在此期间内没有请求该会话,则该会话过期。

关闭浏览器时显然跟这两种情况无关。折衷考虑:用Abandon让用户注销或等Timeout了,在线统计不用很准确的吧。

可能有人较真,关闭浏览器时就得怎么着怎么着的去执行Session_end

答:没有太好的方法,服务器端并不能捕获客户端的浏览器关闭事件,有人用JS脚本去检测关闭事件并去激活注销Session,认为并不是很好的做法,这样只能去针对页来做吧。贴个类似的JS代码:

<script language="javaScript">

function removeline(){

if(event.clientX<0&&event.clientY<0)
{

      document.write('<iframe width="500" height="500"      src="RemoveSession.aspx"></iframe><OBJECT       classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0  id=WebBrowser width=0></OBJECT>');

      document.all.WebBrowser.ExecWB(45,1);

}

}

</script>

RemoveSession.aspx 中写上注销Session的代码:Session.Abandon();

 

用户在关闭浏览器时,也不停止Session,除非用户注销了,用了session.setMaxInactiveInterval(-1);可为什么不行呢?

答:这是误导啊,自动登录都是用Cookie实现的,登录后给客户端一个Cookie,以后浏览器每次都发送发送那个Cookie给服务器端,然后实现自动登录。session永不过期将增加服务器负担,不可取。

4. Application_Error遇到的问题比较少点,相对来说也比较简单,主要是做错误重定向。贴个代码吧:

protected void Application_Error(Object sender, EventArgs e)

{

    Server.Transfer("Error.aspx");

}

提示:务必不要显示可能危害应用程序的错误信息,以防恶意用户。

 

5.说说Application_BeginRequestApplication_EndRequest

上面说到,BeginRequest响应请求时作为 HTTP 执行管线链中的第一个事件发生。多用于给请求的URL重定向,加载模板等等。在此也没有太多的问题。顺便也把HttpModule来说了吧。

可以创建自定义的Http模块。须继承接口IHttpModule。在自定义的HttpModule中的Init方法中,这样写:

         public void Init(HttpApplication application)

    {

        application.BeginRequest +=

            (new EventHandler(this.Application_BeginRequest));

        application.EndRequest +=

            (new EventHandler(this.Application_EndRequest));

    }

看这个代码大家清楚了,这不就正是刚刚提到的Application_BeginRequestApplication_EndRequest么,对,就是他们。

这样自定义了HttpModule还不行,还得在Web.config里注册该模块:

<configuration>

    <system.web>

        <httpModules>

             <add name="TestModule" type="TestModule"/>          

           </httpModules>

    </system.web>

</configuration>

OK,现在没问题 
原创粉丝点击