天天看點

微軟AJax.net源碼初步分析(2)--服務執行流程

我以一個最簡單的helloworld為例,示範AJax.net源碼中調用背景服務的機制,隻是列出一些大體的架構,具體細節我還在研究中:)

不當之處,歡迎指正。

我先把例子中的核心代碼列出,友善大家閱讀。

HelloWorldService服務中:

微軟AJax.net源碼初步分析(2)--服務執行流程

    [WebMethod(EnableSession = true)]

微軟AJax.net源碼初步分析(2)--服務執行流程

    public string HelloWorld(string name)

微軟AJax.net源碼初步分析(2)--服務執行流程

    {

微軟AJax.net源碼初步分析(2)--服務執行流程

        String aaa = Session["name"].ToString();

微軟AJax.net源碼初步分析(2)--服務執行流程

        string hello = String.IsNullOrEmpty(name) ? "無名氏" : name;

微軟AJax.net源碼初步分析(2)--服務執行流程

        hello += "你好,目前伺服器時間是:";

微軟AJax.net源碼初步分析(2)--服務執行流程

        hello += DateTime.Now.ToUniversalTime() + "   " + aaa;

微軟AJax.net源碼初步分析(2)--服務執行流程

        return hello;

微軟AJax.net源碼初步分析(2)--服務執行流程

    }

HelloWorld.aspx檔案:

微軟AJax.net源碼初步分析(2)--服務執行流程

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

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

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

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

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

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

<html>

微軟AJax.net源碼初步分析(2)--服務執行流程

<head id="Head1" runat="server">

微軟AJax.net源碼初步分析(2)--服務執行流程

    <title>Hello</title>

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

<script type="text/javascript">

微軟AJax.net源碼初步分析(2)--服務執行流程

    function SayHello()

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

        var fs = HelloWorldService;

微軟AJax.net源碼初步分析(2)--服務執行流程

        fs.set_defaultSucceededCallback(OnShow);

微軟AJax.net源碼初步分析(2)--服務執行流程

        fs.HelloWorld(document.getElementById("name").value);

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

    function OnShow(result)

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

        var s = document.getElementById("result");

微軟AJax.net源碼初步分析(2)--服務執行流程

        s.innerText = result;

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

</script>

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

</head>

微軟AJax.net源碼初步分析(2)--服務執行流程

<body style="font-size: 12pt">

微軟AJax.net源碼初步分析(2)--服務執行流程

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

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

        <asp:ScriptManager ID="ScriptManager1" runat="server">

微軟AJax.net源碼初步分析(2)--服務執行流程

            <Services>

微軟AJax.net源碼初步分析(2)--服務執行流程

                <asp:ServiceReference Path="~/HelloWorldService.asmx" />

微軟AJax.net源碼初步分析(2)--服務執行流程

            </Services>

微軟AJax.net源碼初步分析(2)--服務執行流程

        </asp:ScriptManager>

微軟AJax.net源碼初步分析(2)--服務執行流程

        <div>

微軟AJax.net源碼初步分析(2)--服務執行流程

        你的名字:

微軟AJax.net源碼初步分析(2)--服務執行流程

        <input type="text" maxlength="20" id="name" />

微軟AJax.net源碼初步分析(2)--服務執行流程

        <input type="button" id="button1" value="問候" onclick="SayHello()" />

微軟AJax.net源碼初步分析(2)--服務執行流程

        <div id="result"></div>

微軟AJax.net源碼初步分析(2)--服務執行流程

        </div>

微軟AJax.net源碼初步分析(2)--服務執行流程

    </form>

微軟AJax.net源碼初步分析(2)--服務執行流程

    </body>

微軟AJax.net源碼初步分析(2)--服務執行流程

</html>

微軟AJax.net源碼初步分析(2)--服務執行流程

背景調用機制分析:(都是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.net源碼初步分析(2)--服務執行流程

        //取得AJax的用戶端腳本名稱

微軟AJax.net源碼初步分析(2)--服務執行流程

        private static string GetFullName(string name, System.Reflection.Assembly assembly)

微軟AJax.net源碼初步分析(2)--服務執行流程

        {

微軟AJax.net源碼初步分析(2)--服務執行流程

            if (assembly != ScriptReference.AtlasFrameworkAssembly)

微軟AJax.net源碼初步分析(2)--服務執行流程

            {

微軟AJax.net源碼初步分析(2)--服務執行流程

                return name;

微軟AJax.net源碼初步分析(2)--服務執行流程

            }

微軟AJax.net源碼初步分析(2)--服務執行流程

            return ("Microsoft.Web.Resources.ScriptLibrary." + name);

微軟AJax.net源碼初步分析(2)--服務執行流程

        }

微軟AJax.net源碼初步分析(2)--服務執行流程

        //取得dll中js檔案的位置

微軟AJax.net源碼初步分析(2)--服務執行流程

        string IClientScriptManager.GetWebResourceUrl(Type type, string resourceName)

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

            return this._clientScriptManager.GetWebResourceUrl(type, resourceName);

微軟AJax.net源碼初步分析(2)--服務執行流程

        }        

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

        //注冊客戶段腳本(寫入頁面的html檔案中去)

微軟AJax.net源碼初步分析(2)--服務執行流程

        void IClientScriptManager.RegisterClientScriptInclude(Type type, string key, string url)

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

            this._clientScriptManager.RegisterClientScriptInclude(type, key, url);

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

        //注冊服務

微軟AJax.net源碼初步分析(2)--服務執行流程

        //取得頁面上有哪些服務,如上面的HelloWorldService.asmx服務,然後調用如下語句

微軟AJax.net源碼初步分析(2)--服務執行流程

        this._clientScriptManager.RegisterClientScriptInclude(type, "HelloWorldService.asmx/jsdebug", "HelloWorldService.asmx/jsdebug");

微軟AJax.net源碼初步分析(2)--服務執行流程

以上主要是使用.net 2.0新增的ClientScriptManager類進行用戶端腳本的注冊,也就是生成我們在頁面上看到的如下一段代碼:

(通過檢視運作時的aspx檔案的html代碼)

<script src="/Web/WebResource.axd?d=7lZSau3voGpyPgiEEMwJxQ2&t=632965017419375000" type="text/javascript"></script>

......

<script src="/Web/WebResource.axd?d=VbevhO3ptb2WYvwQWrgTHKAWH4jfDIInCsIvYHSSJgRDZKhi9uLV9U_0kyOUMuNB32yLgf_UUzCml8vnGl7OI4r89qpFWhjBi2BmMZGBkApjwmG5MAGWzA_yjFYvRA8w2gdgDWR5RgcQF-F7MVigcyaKFVde2W9oIqW8P4zdL9g1&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中調用如下一段代碼:

微軟AJax.net源碼初步分析(2)--服務執行流程

            public void ProcessRequest(HttpContext context)

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

                this._originalHandler.ProcessRequest(context);

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程

                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");

微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程
微軟AJax.net源碼初步分析(2)--服務執行流程

..

微軟AJax.net源碼初步分析(2)--服務執行流程

                context.Response.ContentType = "application/x-javascript";

微軟AJax.net源碼初步分析(2)--服務執行流程

                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}]);

    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}]);

    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>

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,如需轉載請自行聯系原作者

繼續閱讀