根据Visual Studio的例子:客户端回调实现 (C#) 示例 ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_aspnetcon/html/2c688b1a-93a4-4dad-b82b-63974bdbb13e.htm
HTML代码
<%
...
@ Page Language = " C# " AutoEventWireup = " true " CodeFile = " ClientCallbackSample.aspx.cs " Inherits = " ClientCallbackSample "
%>
<!
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
id
="Head1"
runat
="server"
>
<
title
>
演示在 ASP.NET 网页中不经过回发而实现客户端回调
</
title
>
<
script
type
="text/javascript"
>
...
function LookUpStock() ... { var lb = window.document.getElementById( " ListBox1 " ); if (lb.selectedIndex != - 1 ) ... { var product = lb.options[lb.selectedIndex].text; CallServer(product, "" ); } else ... { alert( " 请从上面列表中选择一项产品! " ); } } function ReceiveServerData(rValue) ... { Results.innerText = rValue; }
</
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
<
asp:ListBox
ID
="ListBox1"
Runat
="server"
></
asp:ListBox
>
<
br
/>
<
br
/>
<
button
onclick
="LookUpStock()"
>
Look Up Stock
</
button
>
<
br
/>
<
br
/>
Items in stock:
<
span
id
="Results"
></
span
>
<
br
/>
<
br
/>
<
br
/>
</
div
>
</
form
>
</
body
>
</
html
>
后台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
ClientCallbackSample : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
...
{ protected System.Collections.Specialized.ListDictionary catalog; protected void Page_Load( object sender, EventArgs e) ... { String cbReference = Page.ClientScript.GetCallbackEventReference( this , " arg " , " ReceiveServerData " , " context " ); String callbackScript; callbackScript = " function CallServer(arg, context) " + " { " + cbReference + " } ; " ; Page.ClientScript.RegisterClientScriptBlock( this .GetType(), " CallServer " , callbackScript, true ); // if (!IsPostBack) // { // Label label = new Label(); // label.Text = "中华人民共和国!"; // form1.Controls.Add(label); // } catalog = new System.Collections.Specialized.ListDictionary(); catalog.Add( " monitor " , 12 ); catalog.Add( " laptop " , 10 ); catalog.Add( " keyboard " , 23 ); catalog.Add( " mouse " , 17 ); ListBox1.DataSource = catalog; ListBox1.DataTextField = " key " ; ListBox1.DataBind(); } private string _returnValue; public void RaiseCallbackEvent(String eventArgument) ... { String returnValue; if (catalog[eventArgument] == null ) ... { returnValue = " -1 " ; } else ... { returnValue = catalog[eventArgument].ToString(); } _returnValue = returnValue; } ICallbackEventHandler 成员 #region ICallbackEventHandler 成员 public string GetCallbackResult() ... { return _returnValue; } #endregion }
测试后存在以下问题
HTML的LookUpStock函数中的var lb=document.form1[0].ListBox1出错,改为var lb=window.document.getElementById("ListBox1"]才通过,原因常未弄清楚。 按帮助中源代码调试,在不选择ListBox项就点击Look Up Stock按钮时的JS错误是因为默认情况下,ListBox的selectedIndex为-1,现加入一个判断,当用户还未选择 时点击,给一个提示信息 例子中后台CS代码实现了ICallBackEnevtHandler接口,但是存在两个问题是:该接口必须实现的两个方法第一是public void RaiseCallbackEvent(String eventArgument), 注意是void;第二是public string GetCallbackResult()而例子很奇怪,RaiseCallbackEvent本是void的,他它却是返回string,并且例子中也没有实现GetCallbackResult方法, 难道是Microsoft搞错了...., 导致在调试时报错,解决办法,将RaiseCallbackEvent方法改为void类型,并加入了一个全局的成员变量来将客户端传递的字符串eventArgument纪录, 并由GetCallBackResult返回 。 ClientScript.GetCallbackEventReference方法的context参数还未明白具体的作用是什么。
在完成以上工作以后,我发现每次点击Look Up stock按钮时,程序仍然都会从PageLoad开始执行,我在想这样和Asp.net正常的回发有什么区别呢?难道就只是欺骗了眼睛,页面看起只是局部刷新而已?于是我 写了一小段代码来测试,在页面第一次加载时(也就是!IsPostback)动态创建了一个Label,给Label的Text指定一个值,在页面回发时不重新创建这个Label,在正常情况下,当产生PostBack时,这个Label肯定是 会不见的,但在这个例子中,动态创建的Label在我点击一次,甚至N次按钮之后,依然好好的显示在浏览器上,得出的结论应该是通种方式实现客户端回调,没有丢失客户端状态,所以这种方式的好处就是 帮助中第一段落: 在 ASP.NET 网页的默认模型中,用户会与页交互,单击按钮或执行导致回发的一些其他操作。此时将重新创建页及其控件,并在服务器上运行页代码,且新版本 的页被呈现到浏览器。但是,在有些情况下,需要从客户端运行服务器代码,而不执行回发。如果页中的客户端脚本维护一些状态信息(例如,局部变量值),那么发送页和获取页的新副本就会损坏该状态。此外, 页回发会导致处理开销,这会降低性能,且会让用户不得不等待处理并重新创建页。若要避免丢失客户端状态并且不导致服务器往返的处理开销,可以对 ASP.NET 网页编码,使其能执行客户端回调。在客户端回调中, 客户端脚本函数会向 ASP.NET 网页发送一个请求。该网页运行其正常生命周期的修改版本 — 初始化页并创建其控件和其他成员,然后调用特别标记的方法。该方法执行代码中编写的处理过程,然后向浏览器返回可 由另一客户端脚本函数读取的值。在此过程中,该页一直驻留在浏览器中。