1  什么是Ajax?
AJAX即 “Asynchronous JavaScript and XML”(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术.它的核心就是XMLHttpRequest对象。
下面简单描述一下XMLHttpRequest对象创建和使用的过程。

        var xmlhttp = null;
function CreateXMLHttp() {
try {
xmlhttp = new XMLHttpRequest(); //尝试创建 XMLHttpRequest 对象,除 IE 外的浏览器都支持这个方法。
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.XMLHTTP)
} catch (e) {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
}
return xmlhttp;
}
function Sender() {
xmlhttp = new XMLHttpRequest();
var xmlhttp = CreateXMLHttp();
xmlhttp.open("post", "http://www.baidu.com", true);
xmlhttp.onreadystatechange = getResult;
xmlhttp.send();
}
function getResult() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var result = xmlhttp.responseText;
//var result = xmlhttp.responseXML;
document.getElementById("divResult").innerHTML = result;
}
}

首先实例化一个XMLHttpRequest对象,调用open方法,绑定onreadystatechange事件,最后send一个HTTP请求.如果readyState==4和status==200,则表示请求成功,用返回的结果去填充"divResult".
在ASP.NET中,对这个XMLHttpRequest对象做了一些封装,生成了很多Ajax的应用模式,使我们使用时就像和普通的C#代码一样方便.

2  ASP.NET中的Ajax应用模式
本文介绍ASP.NET中的四种Ajax应用模式:

  • AjaxPro
  • UpdatePanel
  • CallBack
  • PageMethod

 2.1  Ajax Pro

        AjaxPro是比较早的ASP.NET的Ajax框架.其主要原理是
        通过AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default)),为_Default这个Class生成一个ashx文件,这个ashx文件包含了_Default的所有方法
        同时生成一个Javascript对象AjaxPro2Test._Default,AjaxPro2Test指命名空间,这个对象中包含了方法去调用相应的ashx中的方法。

        

    public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default));
}

[AjaxPro.AjaxMethod]
public int Add(int num)
{
return ++num;
}
}
    <script type="text/javascript">
function Add(num) {
var value = AjaxPro2Test._Default.Add(num).value;
document.getElementById('result').innerText = value;
}
</script>

 

 从HttpWatch抓到的结果可以看出,用AjaxPro这个模式,发送的数据和返回的数据比较少。缺点就是不能直接用服务器控件获取值。

 2.2  UpdatePanel

  UpdatePanel是ASP.NET中使用起来最方便的Ajax应用。只要在页面中放一个ScriptManager控件,然后在要实现局部刷新的地方套一个UpdatePanel,就可以轻松实现Ajax功能。

    <form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="txtTime" runat="server"></asp:TextBox>
<asp:Button ID="btnGetTime" runat="server" Text="GetTime"
onclick="btnGetTime_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
    protected void btnGetTime_Click(object sender, EventArgs e)
{
txtTime.Text = DateTime.Now.ToLongTimeString();
}

UpdatePanel的原理是 服务器端通过_ASYNCPOST的值来判断这个请求是不是局部刷新请求,如果是局部刷新请求,则服务器端会对返回的数据进行处理。只返回需要更新的UpdatePanel和ViewState里的数据.组后在客户端对返回的数据进行分检,分别去更新相应的UpdatePanel。
UpdatePanel模式下请求的页面会跑完整个页面生命周期内所有过程。

总结下来UpdatePanel的优点就是使用方便,缺点就是每次请求都会来回发送ViewState里的数据,在性能和数据量上都会造成损失。


2.3   CallBack
所有要实现CallBack的控件都必须继承ICallbackEventHandler借口.
下面是一个简单的实现ICallbackEventHandler借口的控件以及使用方法

 

    public class CallBackControl:CompositeControl,ICallbackEventHandler
{
private string returnValue;
private TextBox txt;
private Button btn;
private DropDownList ddl;

protected override void CreateChildControls()
{
txt = new TextBox();
txt.ID = "txt";
ddl = new DropDownList();
ddl.ID = "ddl";
}

public string Text
{
get
{
EnsureChildControls();
return txt.Text;
}
}

public ListItemCollection Items
{
get
{
EnsureChildControls();
return ddl.Items;
}
}

protected override void OnPreRender(EventArgs e)
{
string callBackScript = Page.ClientScript.GetCallbackEventReference(this, "arg", "CallBackMethod", "context");
string callServer = "function CallServer(arg,context){" + callBackScript + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callServer, true);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"CallBackMethod", "function CallBackMethod(arg,context){alert(context.Name+arg);}", true);
}

protected override void Render(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
txt.RenderControl(writer);
ddl.RenderControl(writer);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Type,"button");
writer.AddAttribute(HtmlTextWriterAttribute.Value,"CallBack");
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "var context=new Object();context.Name='Context';CallServer(document.getElementById('"+txt.ClientID+"').value,context)");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}

#region ICallbackEventHandler Members

public string GetCallbackResult()
{
return returnValue;
}

public void RaiseCallbackEvent(string eventArgument)
{

if (eventArgument == "edward")
{
returnValue = "FoolishMan" + ddl.SelectedValue;// 此处会报错,ddl=null
}
else
{
returnValue = "FoolishMan" + eventArgument;
}
}

#endregion
}

 

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Demo1.aspx.cs" Inherits="JWebControls.ControlClientDemo.Demo1" %>

<%@ Register assembly="JControlClient" namespace="JControlClient" tagprefix="cc1" %>

<!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></title>
<script type="text/javascript">

</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<cc1:CallBackControl ID="CallBackControl1" runat="server" />
</div>
</form>
</body>
</html>

 

 

 

 月UpdatePanel模式类似CallBack模式下,服务器端用_CALLBACKID这个键值对来判断这个请求是不是CallBack请求.不同的是CallBack请求返回的数据很少,而  且请求的页面只会跑页面生命周期内的部分过程。

 

 2.4 PageMethods

    public partial class PageMethod : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}

[WebMethod]
public static string SetValue(string name)
{
HttpContext.Current.Session["name"] = name;
return name;
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PageMethod.aspx.cs" Inherits="JWebControls.ControlClientDemo.PageMethod" %>

<!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></title>
<script type="text/javascript">
function PageMethod1() {
PageMethods.SetValue("edward",Success);
}
function Success(result) {
alert(result);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server">
</asp:ScriptManager>
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<input type="button" value="PageMethod1()" onclick="PageMethod1()" />
</div>
</form>
</body>
</html>

 

 PageMethods和AjaxPro类似,只是PageMethods生成的是WebService不是ashx.

 

 实现Ajax的方法有很多种,在此我只是做了一些小小的归纳,如有错误的地方请谅解。

 

 

 

 

posted on 2012-03-19 16:19  啊熊  阅读(308)  评论(0编辑  收藏  举报