[转]浅谈ASP.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=”form1runat=”server>
<asp:TextBox runat=”serverID=”TextBox1/>
<asp:DropDownList runat=”serverID=”DropDownList1>
<asp:ListItem Text=”Text1Value=”Value1/>
<asp:ListItem Text=”Text2Value=”Value2/>
<asp:ListItem Text=”Text3Value=”Value3/>

      
      asp:DropDownList>
<asp:Button runat=”serverText=”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=”form1method=”postaction=”Default7.aspxid=”form2>
<div>
<input type=”hiddenname=”__VIEWSTATEid=”__VIEWSTATEvalue=”/wEPDwUKMTAxNzk2MjY2OWRkxj+0HeO0c5N0xVutp03x6OdaSpw=” />

      
      div>
<input name=”TextBox1type=”textid=”TextBox1/>
<select name=”DropDownList1id=”DropDownList1>
<option value=”Value1>Text1 
       option> <option value=”Value2>Text2 
        option> <option value=”Value3>Text3 
         option>  
          select> <input type=”submitname=”ctl02value=”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事件。

     所以,如果想在自定义控件可以触发事件,那么就要实现IPostBackEventHandler接口。

 

原文地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值