none
Aspx页面上的服务器端代码在什么阶段执行的? RRS feed

  • 问题

  • 在ASPX页面上 用 <% %> 括起来的代码在什么 阶段执行呢?

    为什么我在 application_EndRequest 中设置的值,在ASPX页面上的 <%%>代码能获取到?

    或者我想知道,难道application_EndRequest 后面还有其他的事件处理程序吗?


    Johnny

    2012年2月26日 13:48

答案


  • Render顺序是RenderControl->Render->RenderChildren ,注意不是平行顺序,而是rendercontrol执行内部会执行render,render内部会执行renderchildren


    RenderChildren 执行的时候,会加载页面标记 内联的写法<%=%>


    所以你要做的就是在RenderControl的时候


            public override void RenderControl(HtmlTextWriter writer)
            {
                base.Render(writer);            writer.Write(“页面执行时间 ”);
            }

    注意这里的writer已经执行完了,所以添加的html会在<html></html>外面,但是这个是最接近显示页面执行时间的事件,因为你要显示的执行时间这个文本本身也是包含在执行时间内的,理论上统计出来是不可能的,所以接近最真实值就可以了

    不过放心,上面的输出,只有在浏览器源文件查看是在<html></html>外面的,实际现代浏览器是会把他放到<body></body>里面的,所以你可以输出一个好看的<div></div>,加上css,也是完全可行的方案


    也可以操作writer,做字符串修改,让标记显示在body里面







    2012年3月11日 3:24
    版主

全部回复

  • ScottGu在一篇博客上的解释

    In most cases, the actual response content is sent to the client after the application instance is finished with the response (which is after EndRequest).

    在大多数情况下,实际的响应内容发送到客户端是在application 实例完成之后进行的,即EndRequest

    ---------------------------

    以上回答是错误的,抱歉

    2012年3月10日 11:10
    版主
  • 我的代码是这样的,在application_EndRequest中将页面执行时间保存在 context.Application 中,然后想在页面上的Literal控件中显示出来。按照您的说法,
    “实际的响应内容发送到客户端是在application 实例 完成之后进行 的“,我想知道这个 “完成之后进行” 可否通过一些事件来接管呢?或者说在页面的哪个事件中可以读取 context.Application 中的值呢?


    Johnny

    2012年3月10日 12:52
  • 用代码试了一下,application_EndRequest 是在RenderControl-》Render-》RenderChildren 之后执行的

    所以本次设定的全局值,是不会出现在本次的Render,即页面上是不存在的

    你的情况是其实每次显示的都是上次的值,只不过你没发现罢了

    设置数据 
            public delegate void EndEventHandler(object sender, EventArgs e);
            public event EndEventHandler EndEvented;


            void Application_BeginRequest(object sender, EventArgs e)
            {
                EndEvented += new EndEventHandler(Global_EndEvented);
                Application["Value"] = "这是开始的数据,会被正常显示";
            }


            void Application_EndRequest(object sender, EventArgs e)
            {
                if (EndEvented != null)
                    EndEvented(sender, e);

            }

            void Global_EndEvented(object sender, EventArgs e)
            {
                Application["Value"] = "这是结束的数据,不会被显示出来";
            } 显示 <%=Application["Value"]%>



    -------

    如果上面的例子还不够清晰的话,请看下面的例子

    设置数据  
    
          public delegate void EndEventHandler(object sender, EventArgs e);
            public event EndEventHandler EndEvented;
    
    
            void Application_BeginRequest(object sender, EventArgs e)
            {
                if (EndEvented == null)
                {
                    Application["Value"] = "这是开始的数据,第一次会被正常显示";   
                }
    
                EndEvented += new EndEventHandler(Global_EndEvented);
            }
    
    
            void Application_EndRequest(object sender, EventArgs e)
            {
                if (EndEvented != null)
                    EndEvented(sender, e);
    
            }
    
            void Global_EndEvented(object sender, EventArgs e)
            {
                Application["Value"] = string.Concat("这是结束的数据,会被下一次显示出来 注意当前时间", DateTime.Now.ToString("HH:mm:ss"));
            }
    
    显示
    
    <%=Application["Value"]%>




    2012年3月11日 0:39
    版主
  • 我也测试了以下,的确每次显示的值都是上次值,谢谢gsrdell的测试。那现在就没有办法得到 application_EndRequest中设置的值吗?我另外的一个设想是将值保存在 http header 中,然后在客户端端读取出来。但是在网上查到的资料说Javascript不支持读取http header。请问gsrdell有什么其他的办法吗?

    Johnny

    2012年3月11日 2:11

  • Render顺序是RenderControl->Render->RenderChildren ,注意不是平行顺序,而是rendercontrol执行内部会执行render,render内部会执行renderchildren


    RenderChildren 执行的时候,会加载页面标记 内联的写法<%=%>


    所以你要做的就是在RenderControl的时候


            public override void RenderControl(HtmlTextWriter writer)
            {
                base.Render(writer);            writer.Write(“页面执行时间 ”);
            }

    注意这里的writer已经执行完了,所以添加的html会在<html></html>外面,但是这个是最接近显示页面执行时间的事件,因为你要显示的执行时间这个文本本身也是包含在执行时间内的,理论上统计出来是不可能的,所以接近最真实值就可以了

    不过放心,上面的输出,只有在浏览器源文件查看是在<html></html>外面的,实际现代浏览器是会把他放到<body></body>里面的,所以你可以输出一个好看的<div></div>,加上css,也是完全可行的方案


    也可以操作writer,做字符串修改,让标记显示在body里面







    2012年3月11日 3:24
    版主
  • 的确像你所说的那样,显示的执行时间这个文本本身也是包含在执行时间内的,所以只能得到一个近似的执行时间。感谢gsralex的解答。


    Johnny

    2012年3月11日 7:25