我以一个最简单的helloworld为例,演示AJax.net源码中调用后台服务的机制,只是列出一些大体的框架,具体细节我还在研究中:)
不当之处,欢迎指正。

我先把例子中的核心代码列出,方便大家阅读。
HelloWorldService服务中:

    [WebMethod(EnableSession = true)]
    public string HelloWorld(string name)
    {
        String aaa = Session["name"].ToString();
        string hello = String.IsNullOrEmpty(name) ? "无名氏" : name;
        hello += "你好,当前服务器时间是:";
        hello += DateTime.Now.ToUniversalTime() + "   " + aaa;
        return hello;
    }

HelloWorld.aspx文件:

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

<%@ Register Assembly="Microsoft.Web.Extensions" Namespace="Microsoft.Web.UI" TagPrefix="asp" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head id="Head1" runat="server">
    <title>Hello</title>

<script type="text/javascript">
    function SayHello()
    {
        var fs = HelloWorldService;
        fs.set_defaultSucceededCallback(OnShow);
        fs.HelloWorld(document.getElementById("name").value);

    }
    function OnShow(result)
    {
        var s = document.getElementById("result");
        s.innerText = result;
    }
</script>
    
</head>
<body style="font-size: 12pt">
    <form id="form1" runat="server">
    
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference Path="~/HelloWorldService.asmx" />
            </Services>
        </asp:ScriptManager>
        <div>
        你的名字:
        <input type="text" maxlength="20" id="name" />
        <input type="button" id="button1" value="问候" onclick="SayHello()" />
        <div id="result"></div>
        </div>
    </form>
    </body>
</html>

后台调用机制分析:(都是Microsoft.Web.Extensions.dll反编译后看到的)
1、在AssemblyInfo.cs中声明了如下一些javascript脚本:
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.Timer.bmp", "image/bmp")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.Background.gif", "image/gif")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.ScriptLibrary.MicrosoftAjaxWebForms.debug.js", "application/x-javascript")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.ScriptLibrary.MicrosoftAjaxRuntime.debug.js", "application/x-javascript")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.ScriptLibrary.MicrosoftAjax.debug.js", "application/x-javascript")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.ScriptLibrary.MicrosoftAjaxWebForms.js", "application/x-javascript")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.ScriptLibrary.MicrosoftAjaxRuntime.js", "application/x-javascript")]
 [assembly: System.Web.UI.WebResource("Microsoft.Web.Resources.ScriptLibrary.MicrosoftAjax.js", "application/x-javascript")]

这些javascript脚本也都是作为资源包含在Microsoft.Web.Extensions.dll中的

2、在ScriptManager的OnPreRender中进行如下操作,进行js代码的注册(有的方法是调用其它类里面的):

        //取得AJax的客户端脚本名称
        private static string GetFullName(string name, System.Reflection.Assembly assembly)
        {
            if (assembly != ScriptReference.AtlasFrameworkAssembly)
            {
                return name;
            }
            return ("Microsoft.Web.Resources.ScriptLibrary." + name);
        }
        //取得dll中js文件的位置
        string IClientScriptManager.GetWebResourceUrl(Type type, string resourceName)
        {
            return this._clientScriptManager.GetWebResourceUrl(type, resourceName);
        }        

        //注册客户段脚本(写入页面的html文件中去)
        void IClientScriptManager.RegisterClientScriptInclude(Type type, string key, string url)
        {
            this._clientScriptManager.RegisterClientScriptInclude(type, key, url);
        }
        //注册服务
        //取得页面上有哪些服务,如上面的HelloWorldService.asmx服务,然后调用如下语句
        this._clientScriptManager.RegisterClientScriptInclude(type, "HelloWorldService.asmx/jsdebug", "HelloWorldService.asmx/jsdebug");

以上主要是使用.net 2.0新增的ClientScriptManager类进行客户端脚本的注册,也就是生成我们在页面上看到的如下一段代码:
(通过查看运行时的aspx文件的html代码)
<script src="/Web/WebResource.axd?d=7lZSau3voGpyPgiEEMwJxQ2&amp;t=632965017419375000" type="text/javascript"></script>
......
<script src="/Web/WebResource.axd?d=VbevhO3ptb2WYvwQWrgTHKAWH4jfDIInCsIvYHSSJgRDZKhi9uLV9U_0kyOUMuNB32yLgf_UUzCml8vnGl7OI4r89qpFWhjBi2BmMZGBkApjwmG5MAGWzA_yjFYvRA8w2gdgDWR5RgcQF-F7MVigcyaKFVde2W9oIqW8P4zdL9g1&amp;t=632985966674218750" type="text/javascript"></script>
<script src="HelloWorldService.asmx/jsdebug" type="text/javascript"></script>

3、通过IHttpHandlerFactory接口对服务进行处理:
在web.config中进行注册:
  <httpHandlers>
   <remove verb="*" path="*.asmx"/>
   <add verb="*" path="*.asmx" validate="false" type="Microsoft.Web.Script.Services.ScriptHandlerFactory, Microsoft.Web.Extensions"/>
  </httpHandlers>

然后在ScriptHandlerFactory中调用如下一段代码:

            public void ProcessRequest(HttpContext context)
            {
                this._originalHandler.ProcessRequest(context);
            }
        
                base._builder.Append(text1).Append(".set_path = function(value) { \r\n/// <summary>Sets the service url.</summary>\r\n/// <param name=\"path\" type=\"String\">The service url.\r\nvar e = Function._validateParams(arguments, [{name: 'path', type: String}]); if (e) throw e; ").Append(text1).Append("._staticInstance._path = value; }\r\n");
                base._builder.Append(text1).Append(".get_path = function() { \r\n/// <summary>Returns the service url.</summary>\r\n/// <returns type=\"String\">The service url.</returns>\r\nreturn ").Append(text1).Append("._staticInstance._path; }\r\n");
                base._builder.Append(text1).Append(".set_timeout = function(value) { \r\n/// <summary>Sets the service timeout.</summary>\r\n/// <param name=\"value\" type=\"Number\">The service timeout.\r\nvar e = Function._validateParams(arguments, [{name: 'timeout', type: Number}]); if (e) throw e; if (value < 0) { throw Error.argumentOutOfRange('value', value, Sys.Res.invalidTimeout); }\r\n").Append(text1).Append("._staticInstance._timeout = value; }\r\n");
                base._builder.Append(text1).Append(".get_timeout = function() { \r\n/// <summary>Returns the service timeout.</summary>\r\n/// <returns type=\"Number\">The service timeout.</returns>\r\nreturn ").Append(text1).Append("._staticInstance._timeout; }\r\n");
                base._builder.Append(text1).Append(".set_defaultUserContext = function(value) { \r\n/// <summary>Sets the service default userContext.</summary>\r\n/// <param name=\"value\">The service default user context.\r\n").Append(text1).Append("._staticInstance._userContext = value; }\r\n");
                base._builder.Append(text1).Append(".get_defaultUserContext = function() { \r\n/// <summary>Returns the service default user context.</summary>\r\n/// <returns>The service default user context.</returns>\r\nreturn ").Append(text1).Append("._staticInstance._userContext; }\r\n");
                base._builder.Append(text1).Append(".set_defaultSucceededCallback = function(value) { \r\n/// <summary>Sets the service default succeeded callback.</summary>\r\n/// <param name=\"value\" type=\"Function\">The service default succeed callback function.\r\nvar e = Function._validateParams(arguments, [{name: 'defaultSucceededCallback', type: Function}]); if (e) throw e; ").Append(text1).Append("._staticInstance._succeeded = value; }\r\n");
                base._builder.Append(text1).Append(".get_defaultSucceededCallback = function() { \r\n/// <summary>Returns the service default succeeded callback.</summary>\r\n/// <returns type=\"Function\">The service default succeeded callback.</returns>\r\nreturn ").Append(text1).Append("._staticInstance._succeeded; }\r\n");
                base._builder.Append(text1).Append(".set_defaultFailedCallback = function(value) { \r\n/// <summary>Sets the service default failed callback function.</summary>\r\n/// <param name=\"value\" type=\"Function\">The service default failed callback function.\r\nvar e = Function._validateParams(arguments, [{name: 'defaultFailedCallback', type: Function}]); if (e) throw e; ").Append(text1).Append("._staticInstance._failed = value; }\r\n");
                base._builder.Append(text1).Append(".get_defaultFailedCallback = function() { \r\n/// <summary>Returns the service default failed callback function.</summary>\r\n/// <returns type=\"Function\">The service default failed callback function.</returns>\r\nreturn ").Append(text1).Append("._staticInstance._failed; }\r\n");
                
                ..
                context.Response.ContentType = "application/x-javascript";
                context.Response.Write(text1);

以上代码实际上就是根据页面上有的服务生成对应的javascript代码,比如我们针对上面的HelloWorldService.asmx服务,就会生成如下一段javascript
代码,注册到页面中去:
var HelloWorldService=function() {
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
HelloWorldService.prototype={
HelloWorld:function(name,succeededCallback, failedCallback, userContext) {
    /// <summary>Invoke the HelloWorld WebMethod</summary>
    /// <param name=\"name\">WebMethod parameter: name(type: String)</param>
    /// <param name=\"succeededCallback\" type=\"function\" optional=\"true\">Callback on successful completion of request</param>
    /// <param name=\"failedCallback\" type=\"function\" optional=\"true\">Callback on failure of request</param>
    /// <param name=\"userContext\" optional=\"true\">User context data (any JavaScript type)</param>
return Sys.Net._WebMethod._invoke.apply(null, [ this, 'HelloWorld','HelloWorldService.HelloWorld',false,{name:name},succeededCallback, failedCallback, userContext]); },_get_path: function() { return HelloWorldService.get_path(); },

set_timeout: function(value) {
    /// <summary>Sets the timeout for this service.</summary>
    /// <param name=\"value\" type=\"Number\">The timeout in milliseconds.</param>
    var e = Function._validateParams(arguments, [{name: 'timeout', type: Number}]);
    if (e) throw e;
    if (value < 0) {
        throw Error.argumentOutOfRange('value', value, Sys.Res.invalidTimeout);
    }
    this._timeout = value;
},
get_timeout: function() {
    /// <summary>Returns the timeout in milliseconds for this service.</summary>
    /// <returns type=\"Number\">The timeout in milliseconds for the service.</returns>
    return this._timeout;
},
set_defaultUserContext: function(value) {
    /// <summary>Sets the default userContext for this service.</summary>
    /// <param name=\"value\">The default userContext for this service.</param>
    this._userContext = value;
},
get_defaultUserContext: function() {
    /// <summary>Returns the default userContext for this service.</summary>
    /// <returns>Returns the default userContext for this service.</returns>
    return this._userContext;
},
set_defaultSucceededCallback: function(value) {
    /// <summary>Sets the default succeededCallback for this service.</summary>
    /// <param name=\"value\" type=\"Function\">The default succeededCallback for this service.</param>
    var e = Function._validateParams(arguments, [{name: 'defaultSucceededCallback', type: Function}]);
    if (e) throw e;
    this._succeeded = value;
},
get_defaultSucceededCallback: function() {
    /// <summary>Returns the default succeededCallback for this service.</summary>
    /// <returns type=\"Function\">Returns the default succeededCallback for this service.</returns>
    return this._succeeded;
},
set_defaultFailedCallback: function(value) {
    /// <summary>Sets the default FailedCallback for this service.</summary>
    /// <param name=\"value\" type=\"Function\">The default FailedCallback for this service.</param>
    var e = Function._validateParams(arguments, [{name: 'set_defaultFailedCallback', type: Function}]);
    if (e) throw e;
    this._failed = value;
},
get_defaultFailedCallback: function() {
    /// <summary>Returns the default failedCallback for this service.</summary>
    /// <returns type=\"Function\">Returns the default failedCallback for this service.</returns>
    return this._failed;
}
}
HelloWorldService._staticInstance = new HelloWorldService();
HelloWorldService.set_path = function(value) {
/// <summary>Sets the service url.</summary>
/// <param name=\"path\" type=\"String\">The service url.
var e = Function._validateParams(arguments, [{name: 'path', type: String}]); if (e) throw e; HelloWorldService._staticInstance._path = value; }
HelloWorldService.get_path = function() {
/// <summary>Returns the service url.</summary>
/// <returns type=\"String\">The service url.</returns>
return HelloWorldService._staticInstance._path; }
HelloWorldService.set_timeout = function(value) {
/// <summary>Sets the service timeout.</summary>
/// <param name=\"value\" type=\"Number\">The service timeout.
var e = Function._validateParams(arguments, [{name: 'timeout', type: Number}]); if (e) throw e; if (value < 0) { throw Error.argumentOutOfRange('value', value, Sys.Res.invalidTimeout); }
HelloWorldService._staticInstance._timeout = value; }
HelloWorldService.get_timeout = function() {
/// <summary>Returns the service timeout.</summary>
/// <returns type=\"Number\">The service timeout.</returns>
return HelloWorldService._staticInstance._timeout; }
HelloWorldService.set_defaultUserContext = function(value) {
/// <summary>Sets the service default userContext.</summary>
/// <param name=\"value\">The service default user context.
HelloWorldService._staticInstance._userContext = value; }
HelloWorldService.get_defaultUserContext = function() {
/// <summary>Returns the service default user context.</summary>
/// <returns>The service default user context.</returns>
return HelloWorldService._staticInstance._userContext; }
HelloWorldService.set_defaultSucceededCallback = function(value) {
/// <summary>Sets the service default succeeded callback.</summary>
/// <param name=\"value\" type=\"Function\">The service default succeed callback function.
var e = Function._validateParams(arguments, [{name: 'defaultSucceededCallback', type: Function}]); if (e) throw e; HelloWorldService._staticInstance._succeeded = value; }
HelloWorldService.get_defaultSucceededCallback = function() {
/// <summary>Returns the service default succeeded callback.</summary>
/// <returns type=\"Function\">The service default succeeded callback.</returns>
return HelloWorldService._staticInstance._succeeded; }
HelloWorldService.set_defaultFailedCallback = function(value) {
/// <summary>Sets the service default failed callback function.</summary>
/// <param name=\"value\" type=\"Function\">The service default failed callback function.
var e = Function._validateParams(arguments, [{name: 'defaultFailedCallback', type: Function}]); if (e) throw e; HelloWorldService._staticInstance._failed = value; }
HelloWorldService.get_defaultFailedCallback = function() {
/// <summary>Returns the service default failed callback function.</summary>
/// <returns type=\"Function\">The service default failed callback function.</returns>
return HelloWorldService._staticInstance._failed; }
HelloWorldService.set_path(\"/Web/HelloWorldService.asmx\");
HelloWorldService.HelloWorld= function(name,onSuccess,onFailed,userContext) {    /// <summary>Invoke the HelloWorld WebMethod</summary>
    /// <param name=\"name\">WebMethod parameter: name(type: String)</param>
    /// <param name=\"succeededCallback\" type=\"function\" optional=\"true\">Callback on successful completion of request</param>
    /// <param name=\"failedCallback\" type=\"function\" optional=\"true\">Callback on failure of request</param>
    /// <param name=\"userContext\" optional=\"true\">User context data (any JavaScript type)</param>
HelloWorldService._staticInstance.HelloWorld(name,onSuccess,onFailed,userContext); }

4、实际调用
这样服务注册好之后,我们在页面上写的
        var fs = HelloWorldService;
        fs.set_defaultSucceededCallback(OnShow);
        fs.HelloWorld(document.getElementById("name").value);
实际上就是调用注册好的javascript脚本,然后这些脚本再通过通用的AJAX连接XML的异步方式调用后台代码就可以了

微软AJax.net源码初步分析(2)--服务执行流程相关推荐

  1. 【Android 插件化】Hook 插件化框架 ( 从源码角度分析加载资源流程 | Hook 点选择 | 资源冲突解决方案 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  2. Picasso源码初步分析

    Picasso工作原理 我们知道使用Picasso最简单的方式来显示一张图片的方法就是如下了 Picasso.with(this).load("http://192.168.56.1:808 ...

  3. RxJava从入门到精通:RxJava源码初步分析

    Rxjava 源码学习(一):基本流程分析 - 知乎Rxjava 源码版本:Rxjava2.2.8 1. Rxjava 的基本实现首先看一下最简单的例子,具体查看其内部实现: 通过以下代码查看 Rxj ...

  4. Shell主要逻辑源码级分析(1)——SHELL运行流程

    2019独角兽企业重金招聘Python工程师标准>>> 版权声明:本文由李航原创文章,转载请注明出处:  文章原文链接:https://www.qcloud.com/communit ...

  5. 从源码角度分析MapReduce的reduce流程

    文章目录 前言 流程图 Reduce都干了哪些事? 源码分析 1.run方法 1.1 比较器getOutputValueGroupingComparator 1.1.1 getOutputKeyCom ...

  6. 从源码角度分析MapReduce的map-output流程

    文章目录 前言 流程图 源码分析 1 runNewMapper方法 2.NewOutputCollector方法 2.1 createSortingCollector方法 2.1.1 collecto ...

  7. springmvc源码阅读3--dispatcherServlet reqeust的执行流程

    一.前言 太多的时候总是会遇到群里面问,报404怎么肥事呀,前台的参数怎么后台收不到呀--,上次就在群里面遇到过,围绕这一个点:input的name值是不是错了呀,人家妹子都截了好几次图说没有问题,然 ...

  8. FlinkSQL源码解析(三)执行流程

    1.前言 前面2部分主要是介绍以下2点: flink sql整体的执行流程大致为:sqlNode --> Operation --> RelNode --> 优化 --> ex ...

  9. wifidog 源码初分析

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://quietmadman.blog.51cto.com/3269500/138629 ...

最新文章

  1. 【Android 逆向】类加载器 ClassLoader ( 类加载时机 | 隐式加载 | 显示加载 | 类加载步骤 | 装载 | 链接 | 初始化 )
  2. 20175212童皓桢 Java实验二-面向对象程序设计实验报告
  3. 前端学习(1539):hello world
  4. MongoDB 的高级查询 aggregate 聚合管道
  5. 提交第一个spark作业到集群运行
  6. 计算SDWebImage缓存大小以及清除
  7. (64)SPI外设驱动用户发送模块(三)(第13天)
  8. 加拿大计算机硕士gpa不够,加拿大研究生留学申请者绩点低怎么办?这四类应对方法你都知道吗?...
  9. 多线程-AbstractQueuedSynchronizer(AQS)
  10. Express-js无法获取我的静态文件,为什么?
  11. 当spark遇见hbase
  12. 互联网晚报 | 7月27日 星期三 | 微信安装包11年膨胀575倍;阿里申请香港纽约双重主要上市;苹果应用商店被曝大量色情应用...
  13. 傅里叶级数 画初音 附底层代码
  14. GitLab实现CICD自动化部署
  15. java前台显示后台数据_Thymeleaf在后台获取数据在前台显示
  16. MTU、MSS、TCP首部、IP首部
  17. 国产linux操作系统深度系统20.3发布(推荐)
  18. Windows10环境下自己配置Pytracking详细流程(有参考博客)
  19. Oracle10g的安装
  20. RHCSA——第四天

热门文章

  1. smarty课程---smarty3的安装和使用
  2. 能量项链(NOIP 2006 提高组)
  3. cookie和session原理
  4. Vijos——T 1082 丛林探险
  5. 关于OnPaint、FormPaint会不停的触发 触发多次的情形---讨论总结
  6. LeetCode-Add Two Numbers
  7. sqlserver常用函数/存储过程/数据库角色
  8. Oracle 数据库创建表空间、创建用户指定表空间
  9. DOS下从硬盘安装XP系统方法与要点
  10. 搜索引擎学习(六)Query的子类查询