RbmxXx's Tech Sky
唯有技术让我成长……

导航

 

和Postback说再见

作者:RbmxXx

时间:2005-2-5

 

本文参考了20048MSDNDino Esposito的一篇文章Scrtipt Callbacks in ASP.NET。原文是基于ASP.NET2.0的基础上,现展示了2.0Script Callback的新功能,然后再讲其原理,从而实现在ASP.NET1.1中的Script Callback。本文则是再原文的基础上除了部分的汉化也加上了自己的想法,并且原文是也许写的比较早,在此文以后ASP.NET2.0结构有了新的改动,本文的所有代码的调试环境是:Windows xp(sp2),VS2005 November Community

 


n
        
ASP.NET1.1中的Postback机制

n         ASP.NET2.0中的新功能Script Callback介绍

n         如何使用Script Callback IN ASP.NET 2.0

n         如何使用Script Callback IN ASP.NET 1.1

n         思考与问题

n         作者信息

ASP.NET1.1中的Postback机制

asp.net1.1中,我们知道每个服务器控件都有一个AutoPostback属性。它的作用是当用户(客户端)修改该控件的值,即也可以说是当该控件的事件触发的时候,客户端就通过JavaScript__doPostback(object,EventArgument)来和服务端实现通信。它使得程序员在实现动态的获取服务端数据变得非常方便。例如:有一个查询成绩的页面,由一个DrowDownlist和一个DataGrid来实现。其中DropDownlist从服务绑定所要查看的学期(2003-2004上半学期,2003-2004下半学期等),DataGrid而是用来显示他在改学期所有科目的成绩,和该学科的学分。在ASP.NET1.1中我们最常使用的方法也就是将DrowDownlistAutoPostback属性设置为True,并把该事件触发服务端后台的某个方法,该方法获取所选择的学期的id号,然后去数据库获得DataTable重新绑定与DataGrid并将它显示出来。在这整个过程中,作为用户肯定是要经历一个刷新页面的过程。如果仅像刚才那个例子所说这个刷新不会很大的影响用户的Experience,不过如果你有一个复杂的填写表单的页面,该页面有大量的Control是相关的,需要更据其它Control的选择情况去动态的绑定数据,那当用户填完这个表单的时候也许眼睛也花了,他也许再也不想经历如此痛苦的折磨了,从Experience方面来讲将是非常差的。在不是从服务端获取大量数据的情况下,我们要如何才能避免这种在用户看似多余的Postback?

ASP.NET2.0中新功能Script Callback介绍

ASP.NET2.0中,客户端的脚本功能已经被扩展了。并且增加了Script Callbacks(通过脚本建立于后台的链接,后文将其翻译为客户端呼叫)。你可以用程序去控制<head>标签,通过程序控制input焦点,读取或者设置页面的标题,并且可以控制button或其他的控件提交到其他任何页面(in the application)。具体您可以查看Beta 1 说明,里面有例子和参考。

为了使用ASP.NET2.0中的客户端呼叫技术,你需要在页面中定义一个触发元件(不是提交按钮Submit button)并且把它绑定上JavaScript代码。这段代码会重新获得当前页面的input数据并且准备去呼叫系统提供的一个称为WebForm_DoCallbackScript函数(Beta1)。这个函数会建立一个和一个指定的远程ASP.NET页面建立HTTP连接。后台侦听到这个来自客户端的呼叫后呢,对此触发一个方法。服务端通过先前的客户端的函数返回一个值。在客户端,通过一个用户自定义的脚本函数来获得服务端的值并且用DHTML将其呈现在页面上。重要的是,这样做客户端和服务端的通信仍旧在进行,但是页面并没有重新刷新。更重要的是,当客户端在获取数据的时候用户仍旧可以在它原来的页面上操作。图片1,显示了客户端呼叫的流程。

 Figer1

                      图片1

如何使用Script Callback IN ASP.NET 2.0

ASP.NET2.0中使用Script Callback 主要有两个步骤。首先,需要写服务端的代码,这段代码将会被客户端所调用。当然,必须前定义数据你将要返回的数据类型。这就要更具你需要声么数据而定了。实际上他们通信的都是用String的,但是这个字符串的内容就可以是多种多样的——JavaScript,XML,’,’分隔的string值,等等。

然后,你需要写客户端的代码去引起一个无刷新的呼叫。远程的响应是建立在一个叫WebForm_DoCallbackJavaScript函数。你其实没有必要去知道这个函数的名字,你可以从Page类的新成员——GetCallbackEventReference()中获得客户端呼叫。

 Finger2

 

 string callbackRef = Page.ClientScript.GetCallbackEventReference(this, "document.all['DropDownList1'].value", "UpdateInfo", "null");

注意:在我当前的版本中,也是最新的版本中GetCallbackEventReference不是Page的一个属性而是Page.ClientScript属性的一个方法,该方法有三个重载详见msdn

而呼叫这个javaScript函数的是绑定在一个可以点击的元素上,例如<button>标记。所以这个可以点击的元素,不能是<asp:button>控件,因为这样的服务端控件客户端呈现为一个提交按钮:

<input type=”submit” id=”button” …>

置于ASP.NET2.0中是如何实现Callback全过程在此省略,详情请看作者原文。

需要说明的是:为了能在服务端检测到页面元素使用了Script Callback 必须在页面中引用以下接口,在ASP.NET1.1中也如此。

<%@ Impements Interface=”System.Web.UI.ICallbackEventHandler” %>

如果控件实现了这个接口,ASP.NET后台就调用RaiseCallbackEvent 方法,并且针对呼叫返回响应。

如下是ICallbackEventHandler 接口中的一个方法:

string RaiseCallbackEvent(string eventArgumen)

当然这个string 是可以表示为任何你所需要的值,如前面所说的XML,JAVASCRIPT,数值,等等。

以下是我仿照作者的Demo更具最新的Freamwork的一个例子:

scriptCallback.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ScriptCallback.aspx.cs" Inherits="ScriptCallback_aspx" %> 

<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 

<head runat="server"> 

    
<title>ScriptCallback</title> 

    
<script language=javascript> 

        
function UpdateInfo(result,context) 

        { 

            var o 
= result.split(","); 

            

            
e_ID.innerHTML = o[0]; 

            
e_UserName.innerHTML = o[1]; 

            
e_Password.innerHTML = o[2]; 

            
e_Authority.innerHTML = o[3]; 

            
e_BlogName.innerHTML = o[4]; 

            
e_Email.innerHTML = o[5]; 

        


    </script
> 

</head> 

<body> 

    
<form id="form1" runat="server"> 

        
<div> 

            
<h1> 

                
<span style="font-family: Verdana">Select a name and click for details</span></h1> 

         

                

                    
<asp:DropDownList DataSourceID="SqlDataSource1" DataTextField="UserName" DataValueField="UserName" 

                        ID
="DropDownList1" runat="server"> 

                    
</asp:DropDownList> 

                    
<button runat=server id=btn>More Info</button> 

                    
<asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:COMMConnectionString %>" 

                        ID
="SqlDataSource1" runat="server" SelectCommand="SELECT [UserName] FROM [UserConfig]"> 

                    
</asp:SqlDataSource> 

                    
&nbsp; 

                    
<table style="width: 506px"> 

                        
<tr> 

                            
<td style="width: 89px"> 

                                ID
</td> 

                            
<td style="width: 311px"> 

                            
<span id="e_ID" /> 

                            
</td> 

                        
</tr> 

                        
<tr> 

                            
<td style="width: 89px; height: 20px"> 

                                UserName
</td> 

                            
<td style="width: 311px; height: 20px;"> 

                            
<span id="e_UserName" /> 

                            
</td> 

                        
</tr> 

                        
<tr> 

                            
<td style="width: 89px"> 

                                Password
</td> 

                            
<td style="width: 311px"> 

                            
<span id="e_Password" /> 

                            
</td> 

                        
</tr> 

                        
<tr> 

                            
<td style="width: 89px"> 

                                Authority
</td> 

                            
<td style="width: 311px"> 

                            
<span id="e_Authority" /> 

                            
</td> 

                        
</tr> 

                        
<tr> 

                            
<td style="width: 89px"> 

                                BlogName
</td> 

                            
<td style="width: 311px"> 

                            
<span id="e_BlogName" /> 

                            
</td> 

                        
</tr> 

                        
<tr> 

                            
<td style="width: 89px"> 

                                Email
</td> 

                            
<td style="width: 311px"> 

                            
<span id="e_Email" /> 

                            
</td> 

                        
</tr> 

                    
</table> 

              

           

        
</div> 

    
</form> 

</body> 

</html> 


后台代码如下:scriptCallback.aspx.cs

显示时效如下图:


using System; 

using System.Data; 

using System.Configuration; 

using System.Collections; 

using System.Web; 

using System.Web.Security; 

using System.Web.UI; 

using System.Web.UI.WebControls; 

using System.Web.UI.WebControls.WebParts; 

using System.Web.UI.HtmlControls; 

  

public partial class ScriptCallback_aspx : System.Web.UI.Page 



    
protected void Page_Load(object sender, EventArgs e) 

    
{        

        
string callbackRef = Page.ClientScript.GetCallbackEventReference(this"document.all['DropDownList1'].value""UpdateInfo""null"); 

           
//给buttom按钮添加事件,该事件由GetCallbackEventReference产生。 

        btn.Attributes[
"onclick"= String.Format("javascript:{0}",callbackRef); 

  

    }
 

    
public virtual string RaiseCallbackEvent(string eventArgument) 

    


        
//int userID = Convert.ToInt16(eventArgument); 

        
//此处本该是更具eventArgument去数据库获取数据的,作为演示就省去了数据连接,直接//更具不同的eventArgument显示既定的数据即可。 

        
string[] buf = new string[6]; 

        

        buf[
0= eventArgument + "'s ID"

        buf[
1= eventArgument; 

        buf[
2= eventArgument + "'s Password"

        buf[
3= eventArgument + "'s Authority"

        buf[
4= eventArgument + "'s BlogName"

        buf[
5= eventArgument + "'s Email"

  

        
return String.Join(",", buf); 

    }
 

}
 

 

 


[续]和Postback说再见 

posted on 2005-02-06 01:51  RbmxXx  阅读(4712)  评论(8编辑  收藏  举报