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

本文通过一个简单的示例,详细解析了AjaxPro的工作机制。包括如何注册类型、生成客户端脚本以及异步调用服务端方法的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

以一个最简单的例子开始:
点击一个客户端button,触发一个javascript函数,执行一个只有一个string参数的服务端方法,返回一个处理过的string,处理方法是将传入的string变成“Hi”+string +“!”;够简单了,为了是不希望罗嗦的代码影响简单的分析;
所有代码如下:
ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test"  %>
None.gif
None.gif
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
None.gif
None.gif
< html  xmlns ="http://www.w3.org/1999/xhtml"   >
None.gif
< head  runat ="server" >
None.gif    
< title > 无标题页 </ title >
ExpandedBlockStart.gifContractedBlock.gif    
< script  type ="text/javascript" > dot.gif
InBlock.gif     
InBlock.gif    
function doTest() 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        AJAXDemo.Examples.Test.TestMethod.GetTest(
"AjaxPro",doTest_callback);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
function doTest_callback(res) dot.gif{
InBlock.gif        alert(res.value);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedBlockEnd.gif    
</ script >
None.gif
</ head >
None.gif
< body >
None.gif    
< form  id ="form1"  runat ="server" >
None.gif    
< div >
None.gif        
< input  id ="Button1"  type ="button"  onclick ="doTest()"  value ="测试" /></ div >
None.gif    
</ form >
None.gif
</ body >
None.gif
</ html >

Test.aspx.cs
None.gif public  partial  class  Test : System.Web.UI.Page
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
protected void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Utility.RegisterTypeForAjax(
typeof(AJAXDemo.Examples.Test.TestMethod));
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

AJAXDemo.Examples.Test
None.gif using  System;
None.gif
using  AjaxPro;
None.gif
None.gif
namespace  AJAXDemo.Examples.Test
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class TestMethod
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public TestMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{}
InBlock.gif
InBlock.gif        [AjaxMethod]
InBlock.gif        
public string GetTest(string testText)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "Hi," + testText + "!";
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

1.首先我们看AjaxPro在页面上给我们生成了什么?
Test[1]
None.gif <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
None.gif
None.gif
< html  xmlns ="http://www.w3.org/1999/xhtml"   >
None.gif
< head >< title >
None.gif    无标题页
None.gif
</ title >
ExpandedBlockStart.gifContractedBlock.gif    
< script  type ="text/javascript" > dot.gif
InBlock.gif     
InBlock.gif    
function doTest() 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        AJAXDemo.Examples.Test.TestMethod.GetTest(
"AjaxPro",doTest_callback);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
function doTest_callback(res) dot.gif{
InBlock.gif        alert(res.value);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedBlockEnd.gif    
</ script >
None.gif
</ head >
None.gif
< body >
None.gif    
< form  name ="form1"  method ="post"  action ="Test.aspx"  id ="form1" >
None.gif
< div >
None.gif
< input  type ="hidden"  name ="__VIEWSTATE"  id ="__VIEWSTATE"  value ="/wEPDwUJNzgzNDMwNTMzZGRFekXifzWDNb+qFWPbJumdlZh/dQ=="   />
None.gif
</ div >
None.gif
None.gif
< script  type ="text/javascript"  src ="/AJAXDemo.2/ajaxpro/prototype.ashx" ></ script >
None.gif
< script  type ="text/javascript"  src ="/AJAXDemo.2/ajaxpro/core.ashx" ></ script >
None.gif
< script  type ="text/javascript"  src ="/AJAXDemo.2/ajaxpro/converter.ashx" ></ script >
None.gif
< script  type ="text/javascript"  src ="/AJAXDemo.2/ajaxpro/AJAXDemo.Examples.Test.TestMethod,App_Code.un7rskvh.ashx" ></ script >
None.gif
None.gif    
< div >
None.gif        
< input  id ="Button1"  type ="button"  onclick ="doTest()"  value ="测试" /></ div >
None.gif    
</ form >
None.gif
</ body >
None.gif
</ html >

一定要注意这几行
None.gif < script type = " text/javascript "  src = " /AJAXDemo.2/ajaxpro/prototype.ashx " ></ script >
None.gif
< script type = " text/javascript "  src = " /AJAXDemo.2/ajaxpro/core.ashx " ></ script >
None.gif
< script type = " text/javascript "  src = " /AJAXDemo.2/ajaxpro/converter.ashx " ></ script >
None.gif
< 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
None.gif addNamespace( " AJAXDemo.Examples.Test " );
None.gifAJAXDemo.Examples.Test.TestMethod_class 
=  Class.create();
ExpandedBlockStart.gifContractedBlock.gifAJAXDemo.Examples.Test.TestMethod_class.prototype 
=  ( new  AjaxPro.AjaxClass()).extend( dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    GetTest: 
function(testText) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
return this.invoke("GetTest"dot.gif{"testText":testText}this.GetTest.getArguments().slice(1));
ExpandedSubBlockEnd.gif    }
,
ExpandedSubBlockStart.gifContractedSubBlock.gif    initialize: 
function() dot.gif{
InBlock.gif        
this.url = '/AJAXDemo.2/ajaxpro/AJAXDemo.Examples.Test.TestMethod,App_Code.un7rskvh.ashx';
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
);
None.gifAJAXDemo.Examples.Test.TestMethod 
=   new  AJAXDemo.Examples.Test.TestMethod_class();

converter.ashx

 

None.gif addNamespace( " Ajax.Web " );
None.gif
None.gifAjax.Web.NameValueCollection 
=   function ()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
this.__type = "System.Collections.Specialized.NameValueCollection";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.add = function(key, value) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if(this[key] == nulldot.gif{
InBlock.gif            
this[key] = value;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.getKeys = function() dot.gif{
InBlock.gif        
var keys = [];
InBlock.gif        
InBlock.gif        
for(key in this)
InBlock.gif            
if(typeof this[key] != "function")
InBlock.gif                keys.push(key);
InBlock.gif            
InBlock.gif        
return keys;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.getValue = function(key) dot.gif{
InBlock.gif        
return this[key];
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.toJSON = function() dot.gif{
InBlock.gif        
var o = this;
InBlock.gif        o.toJSON 
= null;
InBlock.gif        
delete o.toJSON;
InBlock.gif        
return AjaxPro.toJSON(o);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif
None.gifaddNamespace(
" Ajax.Web " );
None.gif
ExpandedBlockStart.gifContractedBlock.gifAjax.Web.DataTable 
=   function (columns, rows)  dot.gif {
InBlock.gif
InBlock.gif    
this.__type = "System.Data.DataTable, System.Data";
InBlock.gif    
this.Columns = new Array();
InBlock.gif    
this.Rows = new Array();
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.addColumn = function(name, type) dot.gif{
InBlock.gif        
var c = new Object();
InBlock.gif        c.Name 
= name;
InBlock.gif        c.__type 
= type;
InBlock.gif        
InBlock.gif        
this.Columns.push(c);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.toJSON = function() dot.gif{
InBlock.gif        
var dt = new Object();
InBlock.gif
InBlock.gif        dt.Columns 
= [];
InBlock.gif        
for(var i=0; i<this.Columns.length; i++)
InBlock.gif            dt.Columns.push([
this.Columns[i].Name, this.Columns[i].__type]);
InBlock.gif
InBlock.gif        dt.Rows 
= [];
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for(var i=0; i<this.Rows.length; i++dot.gif{
InBlock.gif            
var row = [];
InBlock.gif            
for(var j=0; j<this.Columns.length; j++)
InBlock.gif                row.push(
this.Rows[i][this.Columns[j].Name]);
InBlock.gif            dt.Rows.push(row);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
return AjaxPro.toJSON(dt);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.addRow = function(row) dot.gif{
InBlock.gif        
this.Rows.push(row);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if(columns != nulldot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for(var i=0; i<columns.length; i++dot.gif{
InBlock.gif            
this.addColumn(columns[i][0], columns[i][1]);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if(rows != nulldot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for(var i=0; i<rows.length; i++dot.gif{
InBlock.gif            
var row = new Object();
ExpandedSubBlockStart.gifContractedSubBlock.gif            
for(var c=0; c<this.Columns.length && c<rows[i].length; c++dot.gif{
InBlock.gif                row[
this.Columns[c].Name] = rows[i][c];
ExpandedSubBlockEnd.gif            }

InBlock.gif            
this.addRow(row);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gifaddNamespace(
" Ajax.Web " );
None.gif
ExpandedBlockStart.gifContractedBlock.gifAjax.Web.DataSet 
=   function (tables)  dot.gif {
InBlock.gif    
this.__type = "System.Data.DataSet, System.Data";
InBlock.gif    
this.Tables = new Array();
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.addTable = function(table) dot.gif{
InBlock.gif        
this.Tables.push(table);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if(tables != nulldot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for(var i=0; i<tables.length; i++dot.gif{
InBlock.gif            
this.addTable(tables[i]);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
ExpandedBlockStart.gifContractedBlock.gif
function  Person(id)  dot.gif {
InBlock.gif    
this.FirstName = "";
InBlock.gif    
this.FamilyName = "";
InBlock.gif    
this.Age = 0;
InBlock.gif    
this.ID = id;
InBlock.gif    
this.__type = 'AJAXDemo.Examples.Classes.Person, App_Code.un7rskvh, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null';
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gifPerson.prototype.get_FullName 
=   function ()  dot.gif {
InBlock.gif    
return this.FirstName + " " + this.FamilyName;
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gifPerson.prototype.toJSON 
=   function ()  dot.gif {
InBlock.gif    
var o = new Object();
InBlock.gif
InBlock.gif    o.firstName 
= this.FirstName;
InBlock.gif    o.familyName 
= this.FamilyName;
InBlock.gif    o.age 
= this.Age;
InBlock.gif    o.id 
= this.ID;
InBlock.gif
InBlock.gif    
return AjaxPro.toJSON(o);
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gifPerson.prototype.save 
=   function ()  dot.gif {
InBlock.gif    
return Person.save(this);
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gifPerson.save 
=   function (p)  dot.gif {
InBlock.gif    
var ps = new PersonSaver();
InBlock.gif    
return ps.savePerson(p);    // synchronous call
ExpandedBlockEnd.gif
}

None.gif
None.gif
var  PersonSaver  =  Class.create();
ExpandedBlockStart.gifContractedBlock.gifPersonSaver.prototype 
=  ( new  AjaxPro.Request()).extend( dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    savePerson: 
function(p) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
return this.invoke("SavePerson"dot.gif{"p":p}).value;
ExpandedSubBlockEnd.gif    }
,
ExpandedSubBlockStart.gifContractedSubBlock.gif    initialize: 
function() dot.gif{
InBlock.gif        
this.url = "ajaxpro/AJAXDemo.Examples.Classes.Person, App_Code.un7rskvh, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null.ashx";
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
)
None.gif
None.gif
None.gif

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

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

转载于:https://www.cnblogs.com/Hedonister/archive/2006/03/16/351552.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值