微软AJax.net源码初步分析(2)--服务执行流程
不當之處,歡迎指正。
我先把例子中的核心代碼列出,方便大家閱讀。
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&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中調用如下一段代碼:
????????????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)--服务执行流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软官方反间谍流氓软件WindowsDe
- 下一篇: 傲菊