• Dot net 运行的内部机制


    转载:

    当我们把页面中的数据包含在表单中发送到服务器的时候,数据到底是以什么形式发送的?服务器接受到提交的数据后是如何读取这些数据,又是如何要决定来引发事件的?我们怎么样才能让我们自定义的控件能够在服务器端触发事件?为什么服务器控件有的要实IPostBackEventHandler,IPostBackDataHandler?.....

          大家已经在知道,在我们开发ASP.NET网站的时候,每个服务器控件都有自己的ID。为了后面更好的展开,下面我们就来简单的看看这个场景:当我们在浏览器中点击了一个服务器控件,如 Button,此时页面回传给服务器,然后服务器就引发控件的Click等事件,这个场景是简单的不能在简单了。我们来进一步看,我们知道,不是所有的控件都会在服务器端触发事件的,比如 submit按钮,这个按钮也同样可以把表单数据传到服务器,但是这个控件不能在服务器端触发事件。其实在一个页面提交到了服务器之后,服务器就会检查是哪个控件引起了页面提交,然后就把这个控件的ID找到,然后再在我们请求的那个页面,如Default.aspx (假设我们点击按钮,请求的是Default.aspx),去找是否有服务器控件的ID和此时提交页面的ID是一样的,如果有,那么就在页面的生命周期的合适的时候,引发事件,在把处理的结果返回;如果没有,服务器就不做什么了特别的处理。

         还有一点要注意的是,在查找那个控件的ID 的时候,页面(如Default.aspx),已经被编译成为了一个继承自Page的类

         当然,上面说的只是一个很粗略额过程,希望大家有个总体的认识。下面就细致的讲解。

         我通过一个流程来解释:

         1.我们首先请求一个服务器端的页面,如:http://localhost/Demo/Default.aspx。为了方便解释,假设页面只有三个服务器控件:TextBox,DropDowmList,Button

         定义如下: 

    <%@ Page Language=”C#” %>
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” 
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”
    >
    <html xmlns=”http://www.w3.org/1999/xhtml”>
    <head runat=”server”>
    <title>Untitled Page</title>
    </head>
    <body>
    <form id=”form1” runat=”server”>
         
    <asp:TextBox runat=”server” ID=”TextBox1” />


         
    <asp:DropDownList runat=”server” ID=”DropDownList1”>
         
    <asp:ListItem Text=”Text1” Value=”Value1” />
         
    <asp:ListItem Text=”Text2” Value=”Value2” />
         
    <asp:ListItem Text=”Text3” Value=”Value3” />
         
    </asp:DropDownList>


         
    <asp:Button runat=”server” Text=”Submit” />
    </form>
    </body>
    </html>

         在浏览器中,我们在”源“中,看到的如下:


    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”
    >
    <html xmlns=”http://www.w3.org/1999/xhtml”>
    <head>
    <title>Untitled Page </title>
    </head>
    <body>
    <form name=”form1” method=”post” action=”Default7.aspx” id=”form2”>
    <div>
    <input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE”
    value=”/wEPDwUKMTAxNzk2MjY2OWRkxj+0HeO0c5N0xVutp03x6OdaSpw=” />
    </div>
    <input name=”TextBox1” type=”text” id=”TextBox1” />
    <select name=”DropDownList1” id=”DropDownList1”>
    <option value=”Value1”>Text1</option>
    <option value=”Value2”>Text2</option>
    <option value=”Value3”>Text3</option>
    </select>
    <input type=”submit” name=”ctl02” value=”Submit” />
    </form>
    </body>
    </html>

          确实,上面的那些HTML的代码确实没有什么,但是大家注意看看TextBox,DropDownList,它们的ID在服务器端的aspx页面和本地的源中的ID是一样的。

         2.我们在浏览器中的TextBox中输入"xiaoyang",然后DropDowList 选中"Text2",然后我们点击按钮,提交。此时我们提交的数据被包含在表单中的,而且是以这样的格式保存的"TextBox1=xiaoyang&DropDownList1=Value2",不用多说,表单数据是用"&"来分隔的,而且每个分隔的串包含两个部分:ID和值,也就是"键值对"。

         3.数据到了服务器后,ASP.NET就实例化一个 HttpRequest的类,这个类有两个属性 Forms和 QueryString,它们的类型都是NameValueCollection(键值对,大家可以把它看成一个HashTable),然后ASP.NET解析表单数据,表单数据就解析成为了一个个的键值对,然后就保存在Forms(POST提交)或者QueryString中(GET提交)。我们之前是以POST提交为例子的。

         4.之前的事情是发生在页面的生命周期之前的。当页面调用自己的ProcessRequest方法后,就进入了页面生命周期,此时页面就会检查页面中的所有控件,看看它们有哪些实现了IPostBackDataHandler接口,然后把实现了这些接口的控件都放入到一个ArrayList中,然后也检查哪些控件实现了IPostBackEventHandler,也把它们假如到另外的集合中,之后就开发遍历实现了IPostBackDataHandler控件的集合,并且调用IPostBackDataHandler的方法:LoadPostData(string postdatakey,NameValueCollection value)。

         之前说过了的,我们提交的表单的值都保存在了Forms中(它的类型是NameValueCollection 的),所以此时这些值就传入到了这个方法,然后就检查这些值和之前的是不是相同的,我们已经还记得,我们在浏览器中看到页面时,页面中的TextBox 初始时是没有值的,而且DropDownList选择的是Text2,现在我们的值改了,是“xiaoyang"和"Text2".所以这个方法检查的结果是:值变了,返回了true.只要返回了true,那么IPostBackDataHandler的下一个方法就会调用RaisePostDataChangeEvent();这个方法已经注册了事件,到页面生命周期的之后就后引发的。

         5.所以,如果我们开发的自定义控件想要在数据改变的时候引发事件,那么就一定要实现IPostBackDataHandler接口。例子可以参看我的另外的控件开发的系列文章。

         6.现在我们已经说到了数据的改变。下面就看看到底是怎么引发事件的。到了页面开发执行RaisePostbackEvent方法的时候,页面就会遍历实现了IPostBackEventHandler的控件的集合,并且检查是否在页面中存在一个控件:这个控件要实现了IPostBackEventHandler,并且ID和之前使得页面提交到服务器的的那个控件的ID一样。如果有IPostBackEventHandler的RaisePostBackEvent 方法来触发事件(不同控件实现这个方法的方式不同),如Click事件。

  • 相关阅读:
    DevExpress 学习链接
    DevExpress TreeList用法总结
    DevExpress 用户控件 分页(中)
    DevExpress通过girdcontrol实现分页
    DevExpress 操作gridcontrol
    通过c#操作word文档的其他方式
    DocX操作word生成报表
    数学文化 剩余定理
    数学文化 卢卡斯数列和黄金分割
    mac 终端高亮显示~
  • 原文地址:https://www.cnblogs.com/JackieYang/p/1795005.html
Copyright © 2020-2023  润新知