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

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

我先把例子中的核心代码列出,方便大家阅读。
HelloWorldService服务中:
None.gif     [WebMethod(EnableSession  =   true )]
None.gif    
public   string  HelloWorld( string  name)
ExpandedBlockStart.gif    
{
InBlock.gif        String aaa 
= Session["name"].ToString();
InBlock.gif        
string hello = String.IsNullOrEmpty(name) ? "无名氏" : name;
InBlock.gif        hello 
+= "你好,当前服务器时间是:";
InBlock.gif        hello 
+= DateTime.Now.ToUniversalTime() + "   " + aaa;
InBlock.gif        
return hello;
ExpandedBlockEnd.gif    }

HelloWorld.aspx文件:
None.gif <% @ Page Language = " C# "  AutoEventWireup = " true "   CodeFile = " HelloWorld.aspx.cs "  Inherits = " _Default "   %>
None.gif
None.gif
<% @ Register Assembly = " Microsoft.Web.Extensions "  Namespace = " Microsoft.Web.UI "  TagPrefix = " asp "   %>
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 >
None.gif
< head id = " Head1 "  runat = " server " >
None.gif    
< title > Hello </ title >
None.gif
None.gif
< script type = " text/javascript " >
None.gif    function SayHello()
ExpandedBlockStart.gif    
{
InBlock.gif        var fs 
= HelloWorldService;
InBlock.gif        fs.set_defaultSucceededCallback(OnShow);
InBlock.gif        fs.HelloWorld(document.getElementById(
"name").value);
InBlock.gif
ExpandedBlockEnd.gif    }

None.gif    function OnShow(result)
ExpandedBlockStart.gif    
{
InBlock.gif        var s 
= document.getElementById("result");
InBlock.gif        s.innerText 
= result;
ExpandedBlockEnd.gif    }

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

后台调用机制分析:(都是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代码的注册(有的方法是调用其它类里面的):
None.gif          // 取得AJax的客户端脚本名称
None.gif
         private   static   string  GetFullName( string  name, System.Reflection.Assembly assembly)
ExpandedBlockStart.gif        
{
InBlock.gif            
if (assembly != ScriptReference.AtlasFrameworkAssembly)
ExpandedSubBlockStart.gif            
{
InBlock.gif                
return name;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return ("Microsoft.Web.Resources.ScriptLibrary." + name);
ExpandedBlockEnd.gif        }
None.gif          // 取得dll中js文件的位置
None.gif
         string  IClientScriptManager.GetWebResourceUrl(Type type,  string  resourceName)
ExpandedBlockStart.gif        
{
InBlock.gif            
return this._clientScriptManager.GetWebResourceUrl(type, resourceName);
ExpandedBlockEnd.gif        }
        
None.gif
None.gif        
// 注册客户段脚本(写入页面的html文件中去)
None.gif
         void  IClientScriptManager.RegisterClientScriptInclude(Type type,  string  key,  string  url)
ExpandedBlockStart.gif        
{
InBlock.gif            
this._clientScriptManager.RegisterClientScriptInclude(type, key, url);
ExpandedBlockEnd.gif        }
None.gif          // 注册服务
None.gif        
// 取得页面上有哪些服务,如上面的HelloWorldService.asmx服务,然后调用如下语句
None.gif
         this ._clientScriptManager.RegisterClientScriptInclude(type,  " HelloWorldService.asmx/jsdebug " " HelloWorldService.asmx/jsdebug " );
None.gif
以上主要是使用.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中调用如下一段代码:
None.gif              public   void  ProcessRequest(HttpContext context)
ExpandedBlockStart.gif            
{
InBlock.gif                
this._originalHandler.ProcessRequest(context);
ExpandedBlockEnd.gif            }

None.gif        
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
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 " );
None.gif                
None.gif                dot.gif..
None.gif                context.Response.ContentType 
=   " application/x-javascript " ;
None.gif                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的异步方式调用后台代码就可以了


    本文转自永春博客园博客,原文链接:http://www.cnblogs.com/firstyi/archive/2006/11/08/554374.html,如需转载请自行联系原作者


相关文章
|
1月前
|
JavaScript 前端开发 容器
AJAX载入外部JS文件到页面并让其执行的方法(附源码)
AJAX载入外部JS文件到页面并让其执行的方法(附源码)
29 0
|
1月前
|
开发框架 .NET BI
ASP.NET公立医院健康体检信息管理系统源码
健康体检信息管理系统是专门针对医院体检中心的日常业务运作的特点和流程,结合数字化医院建设要求进行设计研发的一套应用系统。该系统覆盖体检中心的所有业务,完成从预约、登记、收费、检查、检验、出报告、分析、报表等所有工作,规范了体检流程,提高了工作效率。体检系统为每个体检者建立一套完整的体检档案,与病人的门诊、住院诊疗信息有机集成, 真正体现数字化医院以病人为中心的建设原则。
40 1
|
1月前
|
开发框架 安全 .NET
ASP.NET三甲医院手术麻醉信息管理系统源码 对接麻醉机、监护仪、血气分析仪
辅助医院建设 •支持三级医院评级需求 •支持智慧医院评级需求 •支持互联互通评级需求 •支持电子病历评级需求
25 0
|
1月前
|
存储 开发框架 前端开发
前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统(LIMS)成品源码 B/S架构
发展历史:实验室信息管理系统(LIMS),就是指通过计算机网络技术对实验的各种信息进行管理的计算机软、硬件系统。也就是将计算机网络技术与现代的管理思想有机结合,利用数据处理技术、海量数据存储技术、宽带传输网络技术、自动化仪器分析技术,来对实验室的信息管理和质量控制等进行全方位管理的计算机软、硬件系统,以满足实验室管理上的各种目标(计划、控制、执行)。
32 1
|
4天前
|
开发框架 前端开发 .NET
LIMS(实验室)信息管理系统源码、有哪些应用领域?采用C# ASP.NET dotnet 3.5 开发的一套实验室信息系统源码
集成于VS 2019,EXT.NET前端和ASP.NET后端,搭配MSSQL 2018数据库。系统覆盖样品管理、数据分析、报表和项目管理等实验室全流程。应用广泛,包括生产质检(如石化、制药)、环保监测、试验研究等领域。随着技术发展,现代LIMS还融合了临床、电子实验室笔记本和SaaS等功能,以满足复杂多样的实验室管理需求。
15 3
LIMS(实验室)信息管理系统源码、有哪些应用领域?采用C# ASP.NET dotnet 3.5 开发的一套实验室信息系统源码
|
1月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
33 0
|
1月前
|
存储 测试技术 计算机视觉
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
|
1月前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
30 0
|
1月前
|
XML 前端开发 JavaScript
jQuery中ajax如何使用
jQuery中ajax如何使用
31 0
N..
|
1月前
|
XML JSON 前端开发
jQuery实现Ajax
jQuery实现Ajax
N..
35 1