这几天,我开始系统学习Asp.Net Ajax,很明显,我已经被她深深吸引了,最近学的东西太多了,唯恐遗忘,于是我觉得,我必须把现在能领会的逐一记录下来。这将会是一个系列,记录我对Asp.Net Ajax的认知历程。
当然,在这个领域,我还是个新手,如果有写的不对或描述不准确的地方,希望多包含,并告诉我,我将感激不尽。
先来看一下下面这张主体构架图(取自Asp.Net Ajax In Action)。
由图示,Asp.Net Ajax构架是由两个框架组成的:客户端框架和服务端框架
客户端框架
客户端框架的核心是Microsoft Ajax脚本库,由若干Javascript文件组成,这个脚本库不仅仅是封装了Ajax,它同时对原始的Javascript语言进行了扩展,Application对象,若干Components,类型系统。在这些扩展的帮助下,我们可以更容易编写面向对象的Javascript,更容易的管理客户端对象,等等。
客户端框架是独立于服务段框架的,因此它可以独立出来应用于任何一种其他语言的开发,而不局限于Asp.Net,使用的时候只需将脚本库文件包含在应用程序中并在页面上引用即可。
不得不提的是,如果你用VS2008,那么它的Javascript Intellisence将让你大开眼界。编写脚本真的变得更加容易了。
服务端框架
Asp.Net Ajax Server Control:即Asp.Net Ajax服务端控件,最重要的控件:"ScriptManager", "UpdatePanel"
Web Services Bridge:使客户端脚本可以调用外部Web Services
Application Services Bridge:使客户端脚本可以访问有关应用程序服务端用户验证、用户资料等信息
客户端为中心的编程模型:
通常我们会编写丰富的客户端Javascript,来跟服务端进行异步交互
看一个简单的客户端异步访问Web Service的例子:
建一个.asmx的Web Service文件: WSUser.asmx
Code
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
namespace Tristan.AjaxCenter.A {
/**//// <summary>
/// Summary description for WSUser
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WSUser : System.Web.Services.WebService {
[WebMethod]
public string GetUserName() {
return "guozhijian";
}
}
}
注意,
[System.Web.Script.Services.ScriptService]是必须的using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
namespace Tristan.AjaxCenter.A {
/**//// <summary>
/// Summary description for WSUser
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WSUser : System.Web.Services.WebService {
[WebMethod]
public string GetUserName() {
return "guozhijian";
}
}
}
然后,在客户端,可以这样调用这个web service方法: ShowUser.aspx
Code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowUser.aspx.cs" Inherits="Tristan.AjaxCenter.A.ShowUser" %>
<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="scriptMgr" runat="server">
<Services>
<asp:ServiceReference Path="~/A/WSUser.asmx" />
</Services>
</asp:ScriptManager>
<div id="divUName"></div>
<script type="text/javascript">
Sys.Application.add_load(showName);
function showName() {
Tristan.AjaxCenter.A.WSUser.GetUserName(getUserNameSucceed);
}
function getUserNameSucceed(r) {
$get("divUName").innerText = r;
}
</script>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowUser.aspx.cs" Inherits="Tristan.AjaxCenter.A.ShowUser" %>
<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="scriptMgr" runat="server">
<Services>
<asp:ServiceReference Path="~/A/WSUser.asmx" />
</Services>
</asp:ScriptManager>
<div id="divUName"></div>
<script type="text/javascript">
Sys.Application.add_load(showName);
function showName() {
Tristan.AjaxCenter.A.WSUser.GetUserName(getUserNameSucceed);
}
function getUserNameSucceed(r) {
$get("divUName").innerText = r;
}
</script>
</div>
</form>
</body>
</html>
服务端为中心的编程模型:
在这个模型下,甚至可以不编写一行Javascript,便可以实现与服务端的异步交互。
看一个简单的例子:
Hello.aspx:
Code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Hello.aspx.cs" Inherits="Tristan.AjaxCenter.Hello" %>
<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="scriptMgr" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="uPanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtUserName" runat="server" />
<asp:Button ID="btnCommit" runat="server" Text="Show Name" onclick="btnCommit_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="uProgress" runat="server">
<ProgressTemplate>
<img src="loading.gif" alt="" />
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Hello.aspx.cs" Inherits="Tristan.AjaxCenter.Hello" %>
<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="scriptMgr" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="uPanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtUserName" runat="server" />
<asp:Button ID="btnCommit" runat="server" Text="Show Name" onclick="btnCommit_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="uProgress" runat="server">
<ProgressTemplate>
<img src="loading.gif" alt="" />
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
</html>
Hello.aspx.cs:
Code
protected void btnCommit_Click(object sender, EventArgs e) {
Thread.Sleep(2000);
txtUserName.Text = "guozhijian";
}
protected void btnCommit_Click(object sender, EventArgs e) {
Thread.Sleep(2000);
txtUserName.Text = "guozhijian";
}
执行后可以看到所谓无刷的异步提交效果。