根据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 网页发送一个请求。该网页运行其正常生命周期的修改版本 — 初始化页并创建其控件和其他成员,然后调用特别标记的方法。该方法执行代码中编写的处理过程,然后向浏览器返回可 由另一客户端脚本函数读取的值。在此过程中,该页一直驻留在浏览器中。
本文介绍了一个ASP.NET客户端回调的C#示例,详细分析了客户端脚本与服务器端代码的交互过程,包括如何实现不经过回发而进行客户端回调,以及在实际应用中遇到的问题及解决方案。
165

被折叠的 条评论
为什么被折叠?



