其中附件代码是我从网上下载,进行研究理解以后,修改成的结果(大家看到可能比较眼熟吧!其实网络的意义本来就是供大家共享的,当时是刚刚同学提醒我的。开个玩笑。)。套入正题!!!
在 ASP.NET 网页的默认模型中,用户会与页交互,单击按钮或执行导致回发的一些其他操作。此时将重新创建页及其控件,并在服务器上运行页代码,且新版本的页被呈现到浏览器。但是,在有些情况下,需要从客户端运行服务器代码,而不执行回发。如果页中的客户端脚本维护一些状态信息(例如,局部变量值),那么发送页和获取页的新副本就会损坏该状态。此外,页回发会导致处理开销,这会降低性能,且会让用户不得不等待处理并重新创建页。
若要避免丢失客户端状态并且不导致服务器往返的处理开销,可以对 ASP.NET 网页编码,使其能执行客户端回调。在客户端回调中,客户端脚本函数会向 ASP.NET 网页发送一个请求。该网页运行其正常生命周期的修改版本 — 初始化页并创建其控件和其他成员,然后调用特别标记的方法。该方法执行代码中编写的处理过程,然后向浏览器返回可由另一客户端脚本函数读取的值。在此过程中,该页一直驻留在浏览器中。
客户端回调组件
创建实现客户端回调的 ASP.NET 页与创建任何 ASP.NET 页类似,但也有些不同。例如,该页必须执行以下操作:
1 实现 ICallbackEventHandler 接口。可以向任何 ASP.NET 网页添加此接口声明。
2 包括一个实现 RaiseCallbackEvent 接口的方法。此方法将由回调来调用,然后它将向 clientCallback 函数返回一个字符串。
此外,该页还必须包含执行以下操作的三个客户端脚本函数:
· 一个函数调用帮助器方法,该方法执行对服务器的实际请求。在此函数中,可以首先执行自定义逻辑以准备事件参数,然后可以将一个字符串作为参数发送到服务器端回调事件处理程序。
· 另一个函数由处理回调事件的服务器代码的结果调用并接收该结果,同时接受表示该结果的字符串。该函数称为 clientCallBack 函数。
· 第三个函数是执行对服务器的实际请求的 Helper 函数,当在服务器代码中使用 GetCallbackEventReference 方法生成对此函数的引用时,由 ASP.NET 自动生成该函数。
客户端回调及回发都是对起始页的请求,因此在 Web 服务器日志中将客户端回调及回发记录为页请求。
下面对ICallbackEventHandler 接口简单介绍
注意:此接口在 .NET Framework 2.0 版中是新增的。
用于指示控件可以作为服务器的回调事件的目标。
命名空间:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
备注
为任何需要接收回调事件的自定义控件实现 ICallbackEventHandler 接口。有关更多信息,请参见在 ASP.NET 网页中不经过回发而实现客户端回调。
实现 ICallbackEventHandler 接口的控件的示例包括 GridView、DetailsView 和 TreeView 控件。当回调事件以实现了 ICallbackEventHandler 接口的控件为目标时,将把事件变量作为参数传递来调用 RaiseCallbackEvent 方法以处理该事件,并且 GetCallbackResult 方法返回回调的结果。
以上是参考msdn的文档。 希望大家不要笑话我。
此处的异步与ajax中的变异以后的以内容为中心的风格有点类时。即:(服务器)响应异步请求生成一段HTML片段,然后将响应的内容赋值给当前文档的一个DOM元素的innerHTML属性。
我个人研究了两天才理解回调机制。以下为我个人实现的Gridview无刷新翻页功能的全部代码。
主要功能:通过客户端发送即将显示的页码。服务端接收该页码,通过sql server2000的一个分页存储过程,进行数据的获取。
我不太会写。先这样写着了,等以后想到了再补充。希望大家给我的意见、建议。在此谢谢大家。
Default.aspx代码页
<! 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 > 客户端回调 </ title >
< style type = " text/CSS " >
body ... {} ... {
font-size: 12px;
color: #525252;
}
td ... {} ... {
font-size: 12px;
color: #525252;
}
th ... {} ... {
font-size: 12px
}
a:link ... {} ... {
color: #000000; text-decoration: none
}
a:visited ... {} ... {
color: #525252; text-decoration: none
}
a:hover ... {} ... {
color: #0095A7; text-decoration: underline }
td.alt_1 ... {} ... {
border-top: 1px solid #d6d6d6;
border-right: 1px solid #d6d6d6;
font-size:12px;
color: #4f6b72;
}
td.alt_2 ... {} ... {
border-top: 1px solid #d6d6d6;
border-right: 1px solid #d6d6d6;
}
td.alt_3 ... {} ... {
border-left: 1px solid #d6d6d6;
border-bottom: 1px solid #d6d6d6;
}
td.alt_4 ... {} ... {
border-left: 1px solid #d6d6d6;
border-right: 1px solid #d6d6d6;
}
</ style >
< script type = " text/javascript " >
// author: EvoRul date:2007-03-25
var PageIndex = 1 ;
function QueryServer(obj)
... {
context = gridspan;
context.innerHTML = "<IMG SRC='images/loading.gif' />数据加载中";
if(obj.value=="")
arg="ServerMethodQuery|1";
else
arg = "ServerMethodQuery|" + obj;
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
}
function ReceiveServerData(result, context)
... {
context.innerHTML = (result.split('$'))[0];
var t1=document.getElementById("RecordSum");
var t2=document.getElementById("PageSum");
var t3=document.getElementById("CurrentPage");
var t5=document.getElementById("LinkUp");
var t6=document.getElementById("Linkdown");
var first=document.getElementById("LinkFrist");
var last=document.getElementById("LinkLast");
var t7=document.getElementById("DropDownList1");
//获取总记录数
t1.innerHTML = (result.split('$'))[1];
//获取页数
t2.innerHTML = (result.split('$'))[2];
//当前页数
t3.innerHTML = (result.split('$'))[3];
//把当前页数赋值给PageIndex
PageIndex=eval((result.split('$'))[3]);
if(PageIndex>1)
...{
t5.innerHTML="<a href="#" οnclick="QueryServer(PageIndex-1)">上一页</a>";
first.innerHTML="<a href="#" οnclick="QueryServer(1)">首页</a>";
}
else
...{
t5.innerHTML = "上一页";
first.innerHTML="首页";
}
if(PageIndex< eval((result.split('$'))[2]))
...{
t6.innerHTML="<a href="#" οnclick="QueryServer(PageIndex+1)">下一页</a>";
last.innerHTML="<a href="#" οnclick="QueryServer("+t2.innerHTML+")">尾页</a>";
}
else
...{
t6.innerHTML="下一页";
last.innerHTML="尾页";
}
t7.value=PageIndex;
}
</ script >
</ head >
< body >
< form id = " form1 " runat = " server " >
< div >
< table style = " width:100%; background-color:#ffffff; margin: 0px; " cellpadding = " 0 " cellspacing = " 0 " border = " 0 " id = " table1 " >
< tr >
< td style = " width:102%; height: 445px; " align = " center " valign = " top " >
< br />
< table border = " 0 " cellpadding = " 0 " cellspacing = " 0 " bordercolorlight = " #000000 " bordercolordark = " #ffffff " style = " font-size: 12px; width: 796px " >
< tr >
< td align = " center " nowrap style = " height: 25px; width: 100%; " >
共有 < asp:Label ID = " RecordSum " runat = " server " /> 条记录 < asp:Label ID = " PageSum " runat = " server " /> 页结果
当前显示为第 < asp:Label ID = " CurrentPage " runat = " server " /> 页 10条 / 页
< asp:Label ID = " LinkFrist " runat = " server " > 首页 </ asp:Label >
< asp:Label ID = " LinkUp " runat = " server " > 上一页 </ asp:Label >
< asp:Label ID = " Linkdown " runat = " server " > 下一页 </ asp:Label >
< asp:Label ID = " LinkLast " runat = " server " > 尾页 </ asp:Label >
跳转至第 < asp:DropDownList ID = " DropDownList1 " runat = " server " >
</ asp:DropDownList >< span id = " SpanIndex " > 页 </ span >
</ td >
</ tr >
</ table >
< span id = " gridspan " >
< asp:GridView ID = " Logs " runat = " server "
GridLines = " Horizontal " PageSize = " 15 "
Width = " 95% " BackColor = " White " BorderColor = " #336666 " BorderStyle = " Double " BorderWidth = " 3px " CellPadding = " 4 " >
< FooterStyle BackColor = " White " ForeColor = " #333333 " />
< PagerStyle BackColor = " #336666 " ForeColor = " White " HorizontalAlign = " Center " /> < RowStyle ForeColor = " #333333 " Height = " 24px " BackColor = " White " />
< SelectedRowStyle BorderColor = " Red " BackColor = " #339966 " Font - Bold = " True " ForeColor = " White " />
< HeaderStyle BackColor = " #336666 " ForeColor = " White " Height = " 30px " Font - Bold = " True " />
< AlternatingRowStyle BorderWidth = " 1px " />
</ asp:GridView > </ span >
</ td >
</ tr >
</ table >
</ div >
</ form >
</ body >
</ html >
Default.aspx.cs代码页
using System.Data;
using System.Configuration;
using System.Web;
using System.IO;
using System.Text;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Globalization;
public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
... {
protected void Page_Load(object sender, EventArgs e)
...{
this.DropDownList1.Attributes.Add("onchange", "QueryServer(this.value);return false;");
if (!IsPostBack)
...{
ServerMethodQuery("1");
intialPageSelect();
}
}
// 回调分页
回调分页#region 回调分页
private string serverReturn;
public int recordAmount = 0, pageAmount = 0;
public string GetCallbackResult()
...{
//为便于查看加载效果,添加延时
System.Threading.Thread.Sleep(1500);
string[] parts = serverReturn.Split('|');
//根据传递的方法名进行调用,并传递相应的参数,目前只支持一个参数
return (string)GetType().GetMethod(parts[0]).Invoke(this, new object[] ...{ parts[1] });
}
public void RaiseCallbackEvent(string eventArgument)
...{
serverReturn = eventArgument;
}
/**//// <summary>
/// 根据从客户端传来的值,对GridView的内容进行更新,并将更新后的GridView的html返回
/// </summary>
/// <param name="arg"></param>
/// <returns></returns>
public string ServerMethodQuery(string arg)
...{
//传入客户端字符串,并用"$"分割
StringBuilder strHtml = new StringBuilder();
//strHtml.Append("$");
strHtml.Append(RenderControl(ShowPage(Int32.Parse(arg))));
strHtml.Append("$");
strHtml.Append(recordAmount.ToString());
strHtml.Append("$");
strHtml.Append(pageAmount.ToString());
strHtml.Append("$");
strHtml.Append(arg.ToString());
strHtml.Append("$");
strHtml.Append("$");
return strHtml.ToString();
}
public override void VerifyRenderingInServerForm(Control control)
...{
// Confirms that an HtmlForm control is rendered for
}
private string RenderControl(Control control)
...{
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
control.RenderControl(writer2);
writer2.Flush();
writer2.Close();
return writer1.ToString();
}
/**//// <summary>
/// 初始化页下拉单
/// </summary>
private void intialPageSelect()
...{
//DownListIndex.Items.Clear();
for (int i = 1; i<= pageAmount; i++)
...{
this.DropDownList1.Items.Add(i.ToString());
}
this.DropDownList1.SelectedIndex = 0;
string df = this.DropDownList1.Items.Count.ToString();
}
public GridView ShowPage(int requestPage)
...{
DataSet dataset = ExcetSql.SqlCurrencyPagination("Customers", "CustomerID", "*", "CustomerID desc", "1=1", requestPage, 10, ref recordAmount, ref pageAmount);
this.Logs.DataSource = dataset.Tables[0];
this.Logs.DataBind();
return this.Logs;
}
#endregion
}
类ExcetSql.cs代码页
using System.Data;
using System.Configuration;
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;
using System.Data.SqlClient;
using System.Drawing;
/**/ /// <summary>
/// ExcetSql 的摘要说明
/// </summary>
public class ExcetSql
... {
/**//// <summary>
/// 数据库连接串
/// </summary>
///
private static string Conn = System.Configuration.ConfigurationManager.ConnectionStrings["Conn"].ConnectionString;
public ExcetSql()
...{
//
// TODO: 在此处添加构造函数逻辑
//
}
/**//// <summary>
/// 分页显示
/// </summary>
/// <param name="tableName">表名</param>
/// <param name="tableId">表关键字</param>
/// <param name="field">需要字段</param>
/// <param name="order">排序字段</param>
/// <param name="where">条件</param>
/// <param name="pageCurrent">显示页</param>
/// <param name="pageSize">每页显示数</param>
/// <param name="recordAmount">记录总数</param>
/// <param name="pageAmount">页总数</param>
/// <returns></returns>
public static DataSet SqlCurrencyPagination(string tableName, string tableId, string field, string order, string where, int pageCurrent, int pageSize, ref int recordAmount, ref int pageAmount)
...{
DataSet dataSet = new DataSet();
SqlConnection SqlConn = new SqlConnection(Conn);
SqlConn.Open();
SqlCommand comm = new SqlCommand("pet_pageshow", SqlConn);
comm.CommandType = System.Data.CommandType.StoredProcedure;
comm.Parameters.Add("@tbname", SqlDbType.NVarChar, 4000).Value = tableName;
comm.Parameters.Add("@FieldKey", SqlDbType.NVarChar, 4000).Value = tableId;
comm.Parameters.Add("@PageCurrent", SqlDbType.Int).Value = pageCurrent;
comm.Parameters.Add("@PageSize", SqlDbType.Int).Value = pageSize;
comm.Parameters.Add("@FieldShow", SqlDbType.NVarChar, 1000).Value = field;
comm.Parameters.Add("@FieldOrder", SqlDbType.NVarChar, 1000).Value = order;
comm.Parameters.Add("@Where", SqlDbType.NVarChar, 1000).Value = where;
comm.Parameters.Add("@PageCount", SqlDbType.Int).Direction = ParameterDirection.Output;
comm.Parameters.Add("@RecordCount", SqlDbType.Int).Direction = ParameterDirection.Output;
SqlDataAdapter data = new SqlDataAdapter(comm);
data.Fill(dataSet);
data.Dispose();
SqlConn.Close();
recordAmount = (int)comm.Parameters["@RecordCount"].Value;
pageAmount = (int)comm.Parameters["@PageCount"].Value;
comm.Dispose();
return dataSet;
}
}
此处为Web.config中数据库连接的代码
<connectionStrings>
<add name="Conn" connectionString="user id=sa;password=(按自己的机器配置密码);database=Northwind;server=127.0.0.1" providerName="System.Data.SqlClient"/>
</connectionStrings>