ASP.NET2.0 开发无刷新页面
ASP.NET2.0 开发无刷新页面
在已经发布的 ASP.NET2.0 中,越来越多的 Ajax 开发包被开发出来的情况下, ASP.NET2.0 自带的无刷新页面技术没有被很多人了解,甚至不少人认为该功能有些“鸡肋”。但如果我们仅仅是在程序中加入很少部分的 Ajax 特性, Atlas 、 Ajax.Net 等就显得有些“杀鸡用牛刀”的感觉了。而且,我认为使用 ASP.NET2.0 提供的方法进行开发并不很复杂,相反,使用很少的代码就可以做出来很棒的效果!
下面我来一步一步的带大家开发无刷新的页面!
第一步:实现 ICallBackEventHandler 接口
ICallbackEventHandler接口位于System.Web.UI命名空间下。在beta2时,ICallbackEventHandler只包含一个RaiseCallbackEvent方法,即处理回调事件,又返回处理结果。在正式版中,它变成了包含GetCallbackResult和RaiseCallbackEvent两个成员方法,第一个用来返回回调事件的结果,第二个用来出来回调事件。这个变化主要是为了编写Web控件而做的改动,具体可以看一下GridView等控件中的实现代码。
建立一个 Web 网站,我们来修改 default.aspx.cs 文件:
1 public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
1 private string str;
2 public void RaiseCallbackEvent(string eventArgument)
3 {
4 //可以根据传递的参数不同,调用不同的处理逻辑
5 str = "从服务器端返回的内容:" + eventArgument;
6 }
7
8 public string GetCallbackResult()
9 {
10 return str;
11 }
12
第二步:注册回调方法 我们在 default.aspx 页面中添加一个 TextBox ,一个 Label 和一个 Html 控件 Button ,并给 Button 添加 onclick事件:
1 <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
2 <input id="Button1" type="button" value="提交到Label1" onclick="CallServer(TextBox1, Label1)"/><br/>
3 <asp:Label ID="Label1" runat="server" Text="Label1:"></asp:Label>
4
1 <script type="text/javascript">
2 //由button调用
3 function CallServer(inputcontrol, context)
4 {
5 context.innerHTML = "Loading";
6 arg = inputcontrol.value;
7 //注册回调方法
8 <%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
9 }
10 //在回调方法中注册的接收返回结果的函数
11 function ReceiveServerData(result, context)
12 {
13 context.innerHTML = result;
14 }
15 </script>
16
好了,一个无刷新的页面就开发完了,它可以将你在 TextBox 中输入的文字,通过服务器代码写回到页面的 Label 中。是不是很简单?你可以运行一下你的程序看看效果啦!
下面我们来分析一下这些代码。 首先,我们看
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
ClientScript是System.Web.UI.Page对象的一个属性,它是System.Web.UI.ClientScriptManager对象。用于管理客户端脚本,GetCallbackEventReference方法用于注册一个服务器端事件的客户端回调。它的第四个参数“Context”非常重要,在上面的代码中可以看到,调用CallServer方法时,传递的Context参数就是Label1,而ReceiveServerData的第二个参数“Context”就是被传递过来的Label1。在我的例子中,Context被用于设定一个用来显示服务端返回结果的控件。其实,你可以将任意的对象赋值给Context,它都会被传递给本地端处理回调返回结果的函数,这样,你就可以根据调用前指定的“上下文”灵活的操作返回结果了!在下面给出的完整例子中,你可以看到一个使用Context做的无刷新显示GridView的例子。
OK,在ASP.NET 2.0中开发具有Ajax特性的东东不难吧!其实就是两步:
1、 在Server端实现ICallbackEventHandler接口,在接口包含的方法中根据传递的参数分别调用不同的处理方法,然后返回结果;
2、 在Client端注册回调函数(当然你也可以在Server端注册),然后实现处理回调结果的函数。其中,如果对Context能灵活运用,你就可以做出非常好的效果。
.ASPX代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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>ASP.NET 2.0 页面提交无刷新演示</title>
<script type="text/javascript">
function CallServer1(inputcontrol, context)
{
context.innerHTML = "<IMG SRC='images/pie.gif' />Loading";
arg = 'ServerMethod1|' + inputcontrol.value;
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData1", "context")%>;
}
function ReceiveServerData1(result, context)
{
context.innerHTML = context.id + ":" + result;
}
function CallServer2(obj)
{
context = gridspan;
context.innerHTML = "<IMG SRC='images/pie.gif' />数据加载中";
arg = "ServerMethod2|" + obj.value;
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData2", "context")%>;
}
function ReceiveServerData2(result, context)
{
context.innerHTML = result;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Demo1:html按钮提交数据</h1><br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<input id="Button1" type="button" value="提交到Label1" onclick="CallServer1(TextBox1, Label1)"/>
<input id="Button2" type="button" value="提交到Label2" onclick="CallServer1(TextBox1, Label2)"/>
<br />
<asp:Label ID="Label1" runat="server" Text="Label1:"></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text="Label2:"></asp:Label>
</div>
<hr />
<div>
<h1>Demo2:服务器按钮提交数据</h1><br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button3" runat="server" Text="Button" /><br />
<asp:Label ID="Label3" runat="server" Text="Label3:"></asp:Label></div>
<hr />
<div>
<h1>Demo3:下拉列表框和gridview绑定数据</h1><br />
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ connectionStrings:test %>"
SelectCommand="select distinct(country) from customers"></asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ connectionStrings:test %>"
SelectCommand="select customerid, companyname, country from customers where country=@Country">
<SelectParameters>
<asp:ControlParameter Name="Country" ControlID="DropDownList1" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<div>
<asp:DropDownList ID="DropDownList1" runat="server" Width="239px"
DataSourceID="SqlDataSource1" DataTextField="Country" DataValueField="Country">
</asp:DropDownList>
</div>
<br />
<span id="gridspan">
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource2">
</asp:GridView>
</span>
</div>
</form>
</body>
</html>
.CS代码
using System;
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.IO;
using System.Globalization;
public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
//注册客户端事件处理方法
Button3.Attributes.Add("onclick", "CallServer1(TextBox2, Label3);return false;");
DropDownList1.Attributes.Add("onchange", "CallServer2(this)");
}
private string serverReturn;
public string GetCallbackResult()
{
//为便于查看加载效果,添加延时
System.Threading.Thread.Sleep(2000);
string[] parts = serverReturn.Split('|');
//根据传递的方法名进行调用,并传递相应的参数,目前只支持一个参数
return (string)GetType().GetMethod(parts[0]).Invoke(this, new object[] { parts[1] });
}
public void RaiseCallbackEvent(string eventArgument)
{
serverReturn = eventArgument;
}
//根据从客户端传来的英文国家名或缩写,翻译成相应的中文国家名
public string ServerMethod1(string arg)
{
string s;
switch (arg.ToLower())
{
case "cn":
case "china":
s = "中国";
break;
case "us":
s = "美国";
break;
default:
s = "未知国家";
break;
}
return s;
}
//根据从客户端传来的值,对GridView的内容进行更新,并将更新后的GridView的html返回
public string ServerMethod2(string arg)
{
DropDownList1.SelectedValue = arg;
GridView1.DataBind();
return RenderControl(GridView1);
}
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();
}
}
webconfig
<configuration>
<appSettings/>
<connectionStrings>
<add name="test" connectionString="server=maxwin;Integrated security=true;database=TestCallBackAjax"/>
</connectionStrings>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>
在已经发布的 ASP.NET2.0 中,越来越多的 Ajax 开发包被开发出来的情况下, ASP.NET2.0 自带的无刷新页面技术没有被很多人了解,甚至不少人认为该功能有些“鸡肋”。但如果我们仅仅是在程序中加入很少部分的 Ajax 特性, Atlas 、 Ajax.Net 等就显得有些“杀鸡用牛刀”的感觉了。而且,我认为使用 ASP.NET2.0 提供的方法进行开发并不很复杂,相反,使用很少的代码就可以做出来很棒的效果!
下面我来一步一步的带大家开发无刷新的页面!
第一步:实现 ICallBackEventHandler 接口
ICallbackEventHandler接口位于System.Web.UI命名空间下。在beta2时,ICallbackEventHandler只包含一个RaiseCallbackEvent方法,即处理回调事件,又返回处理结果。在正式版中,它变成了包含GetCallbackResult和RaiseCallbackEvent两个成员方法,第一个用来返回回调事件的结果,第二个用来出来回调事件。这个变化主要是为了编写Web控件而做的改动,具体可以看一下GridView等控件中的实现代码。
建立一个 Web 网站,我们来修改 default.aspx.cs 文件:
1 public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
1 private string str;
2 public void RaiseCallbackEvent(string eventArgument)
3 {
4 //可以根据传递的参数不同,调用不同的处理逻辑
5 str = "从服务器端返回的内容:" + eventArgument;
6 }
7
8 public string GetCallbackResult()
9 {
10 return str;
11 }
12
第二步:注册回调方法 我们在 default.aspx 页面中添加一个 TextBox ,一个 Label 和一个 Html 控件 Button ,并给 Button 添加 onclick事件:
1 <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
2 <input id="Button1" type="button" value="提交到Label1" onclick="CallServer(TextBox1, Label1)"/><br/>
3 <asp:Label ID="Label1" runat="server" Text="Label1:"></asp:Label>
4
1 <script type="text/javascript">
2 //由button调用
3 function CallServer(inputcontrol, context)
4 {
5 context.innerHTML = "Loading";
6 arg = inputcontrol.value;
7 //注册回调方法
8 <%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
9 }
10 //在回调方法中注册的接收返回结果的函数
11 function ReceiveServerData(result, context)
12 {
13 context.innerHTML = result;
14 }
15 </script>
16
好了,一个无刷新的页面就开发完了,它可以将你在 TextBox 中输入的文字,通过服务器代码写回到页面的 Label 中。是不是很简单?你可以运行一下你的程序看看效果啦!
下面我们来分析一下这些代码。 首先,我们看
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
ClientScript是System.Web.UI.Page对象的一个属性,它是System.Web.UI.ClientScriptManager对象。用于管理客户端脚本,GetCallbackEventReference方法用于注册一个服务器端事件的客户端回调。它的第四个参数“Context”非常重要,在上面的代码中可以看到,调用CallServer方法时,传递的Context参数就是Label1,而ReceiveServerData的第二个参数“Context”就是被传递过来的Label1。在我的例子中,Context被用于设定一个用来显示服务端返回结果的控件。其实,你可以将任意的对象赋值给Context,它都会被传递给本地端处理回调返回结果的函数,这样,你就可以根据调用前指定的“上下文”灵活的操作返回结果了!在下面给出的完整例子中,你可以看到一个使用Context做的无刷新显示GridView的例子。
OK,在ASP.NET 2.0中开发具有Ajax特性的东东不难吧!其实就是两步:
1、 在Server端实现ICallbackEventHandler接口,在接口包含的方法中根据传递的参数分别调用不同的处理方法,然后返回结果;
2、 在Client端注册回调函数(当然你也可以在Server端注册),然后实现处理回调结果的函数。其中,如果对Context能灵活运用,你就可以做出非常好的效果。
.ASPX代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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>ASP.NET 2.0 页面提交无刷新演示</title>
<script type="text/javascript">
function CallServer1(inputcontrol, context)
{
context.innerHTML = "<IMG SRC='images/pie.gif' />Loading";
arg = 'ServerMethod1|' + inputcontrol.value;
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData1", "context")%>;
}
function ReceiveServerData1(result, context)
{
context.innerHTML = context.id + ":" + result;
}
function CallServer2(obj)
{
context = gridspan;
context.innerHTML = "<IMG SRC='images/pie.gif' />数据加载中";
arg = "ServerMethod2|" + obj.value;
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData2", "context")%>;
}
function ReceiveServerData2(result, context)
{
context.innerHTML = result;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Demo1:html按钮提交数据</h1><br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<input id="Button1" type="button" value="提交到Label1" onclick="CallServer1(TextBox1, Label1)"/>
<input id="Button2" type="button" value="提交到Label2" onclick="CallServer1(TextBox1, Label2)"/>
<br />
<asp:Label ID="Label1" runat="server" Text="Label1:"></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text="Label2:"></asp:Label>
</div>
<hr />
<div>
<h1>Demo2:服务器按钮提交数据</h1><br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button3" runat="server" Text="Button" /><br />
<asp:Label ID="Label3" runat="server" Text="Label3:"></asp:Label></div>
<hr />
<div>
<h1>Demo3:下拉列表框和gridview绑定数据</h1><br />
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ connectionStrings:test %>"
SelectCommand="select distinct(country) from customers"></asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ connectionStrings:test %>"
SelectCommand="select customerid, companyname, country from customers where country=@Country">
<SelectParameters>
<asp:ControlParameter Name="Country" ControlID="DropDownList1" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<div>
<asp:DropDownList ID="DropDownList1" runat="server" Width="239px"
DataSourceID="SqlDataSource1" DataTextField="Country" DataValueField="Country">
</asp:DropDownList>
</div>
<br />
<span id="gridspan">
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource2">
</asp:GridView>
</span>
</div>
</form>
</body>
</html>
.CS代码
using System;
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.IO;
using System.Globalization;
public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
//注册客户端事件处理方法
Button3.Attributes.Add("onclick", "CallServer1(TextBox2, Label3);return false;");
DropDownList1.Attributes.Add("onchange", "CallServer2(this)");
}
private string serverReturn;
public string GetCallbackResult()
{
//为便于查看加载效果,添加延时
System.Threading.Thread.Sleep(2000);
string[] parts = serverReturn.Split('|');
//根据传递的方法名进行调用,并传递相应的参数,目前只支持一个参数
return (string)GetType().GetMethod(parts[0]).Invoke(this, new object[] { parts[1] });
}
public void RaiseCallbackEvent(string eventArgument)
{
serverReturn = eventArgument;
}
//根据从客户端传来的英文国家名或缩写,翻译成相应的中文国家名
public string ServerMethod1(string arg)
{
string s;
switch (arg.ToLower())
{
case "cn":
case "china":
s = "中国";
break;
case "us":
s = "美国";
break;
default:
s = "未知国家";
break;
}
return s;
}
//根据从客户端传来的值,对GridView的内容进行更新,并将更新后的GridView的html返回
public string ServerMethod2(string arg)
{
DropDownList1.SelectedValue = arg;
GridView1.DataBind();
return RenderControl(GridView1);
}
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();
}
}
webconfig
<configuration>
<appSettings/>
<connectionStrings>
<add name="test" connectionString="server=maxwin;Integrated security=true;database=TestCallBackAjax"/>
</connectionStrings>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>
加油,哥们,现在开始!