您的位置:首页 > 其它

【AjaxPro实现机制浅析一】AjaxPro内部为我们做什么工作?

2006-03-17 17:38 756 查看
先找个借口

:好早就想分析下AjaxPro的代码实现机制了,一直苦于没时间,现在嘛总算有那么丁点了,开篇了,慢慢分析……

以一个最简单的例子开始:
点击一个客户端button,触发一个javascript函数,执行一个只有一个string参数的服务端方法,返回一个处理过的string,处理方法是将传入的string变成“Hi”+string +“!”;够简单了,为了是不希望罗嗦的代码影响简单的分析;
所有代码如下:




Test.aspx




<%

@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>




<!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 doTest()






{


AJAXDemo.Examples.Test.TestMethod.GetTest("AjaxPro",doTest_callback);


}






function doTest_callback(res)

{


alert(res.value);


}





</script>


</head>


<body>


<form id="form1" runat="server">


<div>


<input id="Button1" type="button" onclick="doTest()" value="测试"/></div>


</form>


</body>


</html>






Test.aspx.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;


using AjaxPro;




public partial class Test : System.Web.UI.Page






{


protected void Page_Load(object sender, EventArgs e)






{


Utility.RegisterTypeForAjax(typeof(AJAXDemo.Examples.Test.TestMethod));


}


}




AJAXDemo.Examples.Test.TestMethod


using System;


using AjaxPro;






/**//// <summary>


/// TestMethod 的摘要说明


/// </summary>


namespace AJAXDemo.Examples.Test






{


public class TestMethod






{


public TestMethod()






{


//


// TODO: 在此处添加构造函数逻辑


//


}




[AjaxMethod]


public string GetTest(string testText)






{


return "Hi," + testText + "!";


}


}


}

1.首先我们看AjaxPro在页面上给我们生成了什么?




Test[1]


<!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>




<script type="text/javascript">






function doTest()






{


AJAXDemo.Examples.Test.TestMethod.GetTest("AjaxPro",doTest_callback);


}






function doTest_callback(res)

{


alert(res.value);


}





</script>


</head>


<body>


<form name="form1" method="post" action="Test.aspx" id="form1">


<div>


<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGRFekXifzWDNb+qFWPbJumdlZh/dQ==" />


</div>






<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/prototype.ashx"></script>


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/core.ashx"></script>


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/converter.ashx"></script>


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx"></script>




<div>


<input id="Button1" type="button" onclick="doTest()" value="测试"/></div>


</form>


</body>


</html>

一定要注意这几行


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/prototype.ashx"></script>


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/core.ashx"></script>


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/converter.ashx"></script>


<script type="text/javascript" src="/AJAXDemo.2/ajaxpro/AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx"></script>

通过使用http://localhost:3578/AJAXDemo.2/ajaxpro/prototype.ashxhttp://localhost:3578/AJAXDemo.2/ajaxpro/core.ashx不难发现,其中前面两个是源代码中带的两个js文件(core.js和prototype.js)转化出来的,基本内容也跟原来的文件一样,而converter.ashx和AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx里面有什么呢?看下面:




AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx


addNamespace("AJAXDemo.Examples.Test");


AJAXDemo.Examples.Test.TestMethod_class = Class.create();




AJAXDemo.Examples.Test.TestMethod_class.prototype = (new AjaxPro.AjaxClass()).extend(

{




GetTest: function(testText)

{




return this.invoke("GetTest",

{"testText":testText}, this.GetTest.getArguments().slice(1));


},




initialize: function()

{


this.url = '/AJAXDemo.2/ajaxpro/AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx';


}


});


AJAXDemo.Examples.Test.TestMethod = new AJAXDemo.Examples.Test.TestMethod_class();




converter.ashx


addNamespace("Ajax.Web");




Ajax.Web.NameValueCollection = function()






{


this.__type = "System.Collections.Specialized.NameValueCollection";






this.add = function(key, value)

{




if(this[key] == null)

{


this[key] = value;


}


}







this.getKeys = function()

{


var keys = [];





for(key in this)


if(typeof this[key] != "function")


keys.push(key);





return keys;


}







this.getValue = function(key)

{


return this[key];


}







this.toJSON = function()

{


var o = this;


o.toJSON = null;


delete o.toJSON;


return AjaxPro.toJSON(o);


}


}










addNamespace("Ajax.Web");






Ajax.Web.DataTable = function(columns, rows)

{




this.__type = "System.Data.DataTable, System.Data";


this.Columns = new Array();


this.Rows = new Array();






this.addColumn = function(name, type)

{


var c = new Object();


c.Name = name;


c.__type = type;





this.Columns.push(c);


}






this.toJSON = function()

{


var dt = new Object();




dt.Columns = [];


for(var i=0; i<this.Columns.length; i++)


dt.Columns.push([this.Columns[i].Name, this.Columns[i].__type]);




dt.Rows = [];




for(var i=0; i<this.Rows.length; i++)

{


var row = [];


for(var j=0; j<this.Columns.length; j++)


row.push(this.Rows[i][this.Columns[j].Name]);


dt.Rows.push(row);


}




return AjaxPro.toJSON(dt);


}






this.addRow = function(row)

{


this.Rows.push(row);


}






if(columns != null)

{




for(var i=0; i<columns.length; i++)

{


this.addColumn(columns[i][0], columns[i][1]);


}


}






if(rows != null)

{




for(var i=0; i<rows.length; i++)

{


var row = new Object();




for(var c=0; c<this.Columns.length && c<rows[i].length; c++)

{


row[this.Columns[c].Name] = rows[i][c];


}


this.addRow(row);


}


}


}






addNamespace("Ajax.Web");






Ajax.Web.DataSet = function(tables)

{


this.__type = "System.Data.DataSet, System.Data";


this.Tables = new Array();






this.addTable = function(table)

{


this.Tables.push(table);


}






if(tables != null)

{




for(var i=0; i<tables.length; i++)

{


this.addTable(tables[i]);


}


}


}


















function Person(id)

{


this.FirstName = "";


this.FamilyName = "";


this.Age = 0;


this.ID = id;


this.__type = 'AJAXDemo.Examples.Classes.Person, App_Code.urx4hqkg, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null';


}






Person.prototype.get_FullName = function()

{


return this.FirstName + " " + this.FamilyName;


}






Person.prototype.toJSON = function()

{


var o = new Object();




o.firstName = this.FirstName;


o.familyName = this.FamilyName;


o.age = this.Age;


o.id = this.ID;




return AjaxPro.toJSON(o);


}






Person.prototype.save = function()

{


return Person.save(this);


}






Person.save = function(p)

{


var ps = new PersonSaver();


return ps.savePerson(p); // synchronous call


}




var PersonSaver = Class.create();




PersonSaver.prototype = (new AjaxPro.Request()).extend(

{




savePerson: function(p)

{




return this.invoke("SavePerson",

{"p":p}).value;


},




initialize: function()

{


this.url = "ajaxpro/AJAXDemo.Examples.Classes.Person, App_Code.urx4hqkg, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null.ashx";


}


})







正因为是有了上面四个ashx文件我们的
function doTest()
{
AJAXDemo.Examples.Test.TestMethod.GetTest("AjaxPro",doTest_callback);
}
才得以异步执行,这些ashx文件又是怎么生成到页面上的,那得归功于web.config的相关配置和下面这句代码:
Utility.RegisterTypeForAjax(typeof(AJAXDemo.Examples.Test.TestMethod));

至于Utility.RegisterTypeForAjax方法产生的一序列动作我将在后文中继续说明,有兴趣的可以自己跟踪下这些代码的执行。
[未完待续]

http://hedonister.cnblogs.com/archive/2006/03/16/351552.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: