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

ajax

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

以一个最简单的例子开始:
点击一个客户端button,触发一个javascript函数,执行一个只有一个string参数的服务端方法,返回一个处理过的string,处理方法是将传入的string变成“Hi”+string +“!”;够简单了,为了是不希望罗嗦的代码影响简单的分析;
所有代码如下:
<%@ 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" value="测试"/></div>
    </form>
</body>
</html>
Test.aspx.cs
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
using System;
using AjaxPro;

namespace AJAXDemo.Examples.Test
{
    public class TestMethod
    {
        public TestMethod()
        {}

        [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.un7rskvh.ashx"></script>

    <div>
        <input id="Button1" type="button" 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.ashx和http://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.un7rskvh.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.un7rskvh, 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.un7rskvh, 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方法产生的一序列动作我将在后文中继续说明,有兴趣的可以自己跟踪下这些代码的执行。

 

时间: 2024-09-12 20:46:55

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

PgSQL · 特性分析 · checkpoint机制浅析

背景 上期月报PgSQL · 特性分析 · Write-Ahead Logging机制浅析中简单介绍了PostgreSQL中WAL机制,其中讲到如果是创建checkpoint会触发刷新xlog日志页到磁盘,本文主要分析下PostgreSQL中checkpoint机制. checkpoint又名检查点,一般checkpoint会将某个时间点之前的脏数据全部刷新到磁盘,以实现数据的一致性与完整性.目前各个流行的关系型数据库都具备checkpoint功能,其主要目的是为了缩短崩溃恢复时间,以Oracl

浅析Discuz出现“内部错误,无法显示此内容”的解决方案

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断淘宝客 站长团购 云主机 技术大厅 前一段时间帮一个朋友修改用DZ程序做的网站的模板的时候出现了问题,就是网站突然出现"内部错误,无法显示此内容"问题.大家都知道DZ是完全把主体程序和前端模板拆开的,这一点也可以说是一套优秀程序的一个特征,这一点全球知名的开源程序WordPress也是如此.而DZ还有一个易用的功能就是模块DIY功能,这个功能可以让很

SQL Server事务遭遇网络异常时的处理机制浅析

SQL Server数据库中,如果应用程序正在执行一个事务的时候突然遭遇了网络异常,例如网络掉包,网络中断等,那么这个事务会怎么样? SQL Server数据库是通过什么机制来判断处理呢? 估计很多人跟我一样都有不少疑问, 我们下面构造一个测试实验来测试验证一下.如下所示:     步骤1:在客户端连使用SSMS工具连接到测试数据库,执行下面脚本,显性事务既不提交也不回滚.模拟事务正在执行当中.   USE AdventureWorks2012; GO SELECT@@SPID;     BEG

Android开发之广播机制浅析

对于了解Android程序设计的人都知道,广播是Android开发中的一个重要的功能,在Android里面有各式各样的广播,比如:电池的状态变化.信号的强弱状态.电话的接听和短信的接收等等,今天本文就来给大家简单介绍一下系统发送.监听这些广播的机制. Android中的广播机制基本如下图所示: 那广播在Android程序中到底是如何运行的呢?下面将以代码的形式给大家好好分析一下: 一.发送广播 Intent是Activity中发送广播的桥梁,通过他我们可以轻松的将广播发送到系统中,具体的实现如下

PgSQL · 特性分析 · MVCC机制浅析

背景 我们在使用PostgreSQL的时候,可能会碰到表膨胀的问题(关于表膨胀可以参考之前的月报),即表的数据量并不大,但是占用的磁盘空间比较大,查询比较慢.为什么PostgreSQL有可能发生表膨胀呢?这是因为PostgreSQL引入了MVCC机制来保证事务的隔离性,实现数据库的隔离级别. 在数据库中,并发的数据库操作会面临脏读(Dirty Read).不可重复读(Nonrepeatable Read).幻读(Phantom Read)和串行化异常等问题,为了解决这些问题,在标准的SQL规范中

Spring中应用反射机制浅析

我们知道,Spring中大量使用了反射机制,那么究竟是什么地方使用了呢?就从源头说起吧.   一  反射源头Class类 对类的概念我们已经非常熟悉了.比如可以有Student这个类,Person这个类.但是我们要知道,有一个叫Class的类,它是反射的源头.   正常方式:通过完整的类名->通过new实例化->取得实例化对象 反射方式:实例化对象->getClass()方法->通过完整的类名   一个简单的例子:   package cn.classes; public clas

浏览器缓存机制浅析(转)

非HTTP协议定义的缓存机制 浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires: Cache-control等).但是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者可以在HTML页面的<head>节点中加入<meta>标签,代码如下: <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 上述代码的作用是告诉浏览器当前页面不被缓存,每

PgSQL · 特性分析 · Write-Ahead Logging机制浅析

WAL机制简介 WAL即 Write-Ahead Logging,是一种实现事务日志的标准方法.WAL 的中心思想是先写日志,再写数据,数据文件的修改必须发生在这些修改已经记录在日志文件中之后.采用WAL日志的数据库系统在事务提交时,WAL机制可以从两个方面来提高性能: 多个client写日志文件可以通过一次 fsync()来完成 日志文件是顺序写的,同步日志的开销要远比同步数据页的开销要小 总体来说,使用了WAL机制之后,磁盘写操作只有传统的回滚日志的一半左右,大大提高了数据库磁盘I/O操作的

网络分销机制浅析-联盟营销和DropShipping代销

本文为2010年第四期<销售与市场>渠道版专稿 联盟营销(Affiliate Marketing)的概念其实就是将线下销售中已经使用了多年的"你帮我销售,我付你佣金"搬到线上的电子商务交易中来. 在90年代的第一波电子商务热潮中,一家名为CDNOW的音乐零售公司(后续被Amazon收购)最早推出了自己的联盟营销制度,但这个概念要等到亚马逊(Amazon)在1996年大规模推广自己的联盟营销制度后才开始被越来越多人熟悉.简单的说就是让其他网站都可以通过图片或者文字链接的方式为