【AjaxPro实现机制浅析二】*.ashx文件是怎么来的?
上篇 说到AjaxPro为我们生成了四个ashx文件来达到异步调用的目的,这次呢,就说说这些ashx文件是怎么生成的;
核心部分是其web.config配置了httpHandlers 元素
![]() <httpHandlers>
<httpHandlers>
![]() <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/>
      <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/>
![]() </httpHandlers>
作用是:对ajaxpro目录下的*.ashx文件的POST,GET请求交由程序集AjaxPro下的AjaxPro.AjaxHandlerFactory类来处理;
</httpHandlers>
作用是:对ajaxpro目录下的*.ashx文件的POST,GET请求交由程序集AjaxPro下的AjaxPro.AjaxHandlerFactory类来处理;
ps:关于httpHandlers的说明可以参看下面几个连接
1.httpHandlers 元素(ASP.NET 设置架构)
2.Microsoft ASP.NET 快速入门教程
3.ASP.NET中的Http Handles
先看看实现IHttpHandlerFactory接口的AjaxHandlerFactory类,只实现了GetHandler方法
其中对core,prototype的处理没什么可说,只是简单的通过EmbeddedJavaScriptHandler的ProcessRequest中将js写入.ashx文件,而converter比较复杂留代下次再做详细分析;这里就重点看看AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx是怎么来的了;
我跟踪了下代码的运行,在页面加载的时候自定义 HttpHandler 启用 HTTP Web 请求的处理ProcessRequest,也就是进入AjaxHandlerFactory类GetHandler方法的如下入口
![]() default:
default:
![]()
![]() if(Utility.Settings.UrlNamespaceMappings.Contains(filename))
                            if(Utility.Settings.UrlNamespaceMappings.Contains(filename))
![]() t = Type.GetType(Utility.Settings.UrlNamespaceMappings[filename].ToString());
                                t = Type.GetType(Utility.Settings.UrlNamespaceMappings[filename].ToString());
![]()
![]() if(t == null)
                            if(t == null)
![]() t = Type.GetType(filename);
                                t = Type.GetType(filename);
![]()
![]() return new TypeJavaScriptHandler(t);
                            return new TypeJavaScriptHandler(t);
TypeJavaScriptHandler也实现了IHttpHandler接口,其ProcessRequest方法如下:
![]() public void ProcessRequest(HttpContext context)
public void ProcessRequest(HttpContext context)
![]() {
        {
![]() // The request was not a request to invoke a server-side method.
            // The request was not a request to invoke a server-side method.
![]() // Now, we will render the Javascript that will be used on the
            // Now, we will render the Javascript that will be used on the
![]() // client to run as a proxy or wrapper for the methods marked
            // client to run as a proxy or wrapper for the methods marked
![]() // with the AjaxMethodAttribute.
            // with the AjaxMethodAttribute.
![]()
![]() if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript");
            if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript");
![]() 
        
![]() System.Reflection.MethodInfo[] mi = type.GetMethods();
            System.Reflection.MethodInfo[] mi = type.GetMethods();
![]() 
            
![]() // Check wether the javascript is already rendered and cached in the
            // Check wether the javascript is already rendered and cached in the
![]() // current context.
            // current context.
![]() 
            
![]() string etag = context.Request.Headers["If-None-Match"];
            string etag = context.Request.Headers["If-None-Match"];
![]() string modSince = context.Request.Headers["If-Modified-Since"];
            string modSince = context.Request.Headers["If-Modified-Since"];
![]() string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
            string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
![]()
![]() if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path))
            if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path))
![]() {
            {
![]() foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys)
                foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys)
![]() {
                {
![]() if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path)
                    if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path)
![]() {
                    {
![]() path = key;
                        path = key;
![]() break;
                        break;
![]() }
                    }
![]() }
                }
![]() }
            }
![]()
![]() if(context.Cache[path] != null)
            if(context.Cache[path] != null)
![]() {
            {
![]() CacheInfo ci = (CacheInfo)context.Cache[path];
                CacheInfo ci = (CacheInfo)context.Cache[path];
![]()
![]() if(etag != null)
                if(etag != null)
![]() {
                {
![]() if(etag == ci.ETag)        // TODO: null check
                    if(etag == ci.ETag)        // TODO: null check
![]() {
                    {
![]() context.Response.StatusCode = 304;
                        context.Response.StatusCode = 304;
![]() return;
                        return;
![]() }
                    }
![]() }
                }
![]() 
                
![]() if(modSince != null)
                if(modSince != null)
![]() {
                {
![]() try
                    try
![]() {
                    {
![]() DateTime modSinced = Convert.ToDateTime(modSince.ToString()).ToUniversalTime();
                        DateTime modSinced = Convert.ToDateTime(modSince.ToString()).ToUniversalTime();
![]() if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0)
                        if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0)
![]() {
                        {
![]() context.Response.StatusCode = 304;
                            context.Response.StatusCode = 304;
![]() return;
                            return;
![]() }
                        }
![]() }
                    }
![]() catch(Exception)
                    catch(Exception)
![]() {
                    {
![]() if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "The header value for If-Modified-Since = " + modSince + " could not be converted to a System.DateTime.");
                        if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "The header value for If-Modified-Since = " + modSince + " could not be converted to a System.DateTime.");
![]() }
                    }
![]() }
                }
![]() }
            }
![]()
![]() etag = type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern);
            etag = type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern);
![]() etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
            etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
![]()
![]() DateTime now = DateTime.Now;
            DateTime now = DateTime.Now;
![]() DateTime lastMod = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
            DateTime lastMod = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
![]()
![]() context.Response.AddHeader("Content-Type", "application/x-javascript");
            context.Response.AddHeader("Content-Type", "application/x-javascript");
![]() context.Response.ContentEncoding = System.Text.Encoding.UTF8;
            context.Response.ContentEncoding = System.Text.Encoding.UTF8;
![]() context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
            context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
![]() context.Response.Cache.SetETag(etag);
            context.Response.Cache.SetETag(etag);
![]() context.Response.Cache.SetLastModified(lastMod);
            context.Response.Cache.SetLastModified(lastMod);
![]()
![]() // Ok, we do not have the javascript rendered, yet.
            // Ok, we do not have the javascript rendered, yet.
![]() // Build the javascript source and save it to the current
            // Build the javascript source and save it to the current
![]() // Application context.
            // Application context.
![]()
![]() System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
![]()
![]()
![]() AjaxNamespaceAttribute[] cma = (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
            AjaxNamespaceAttribute[] cma = (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
![]() string clientNS = type.FullName;
            string clientNS = type.FullName;
![]()
![]() if(cma.Length > 0 && cma[0].ClientNamespace != null)
            if(cma.Length > 0 && cma[0].ClientNamespace != null)
![]() {
            {
![]() if(cma[0].ClientNamespace.IndexOf(".") > 0)
                if(cma[0].ClientNamespace.IndexOf(".") > 0)
![]() sb.Append("addNamespace(\"" + cma[0].ClientNamespace + "\");\r\n");
                    sb.Append("addNamespace(\"" + cma[0].ClientNamespace + "\");\r\n");
![]()
![]() clientNS = cma[0].ClientNamespace;
                clientNS = cma[0].ClientNamespace;
![]() }
            }
![]() else
            else
![]() {
            {
![]() sb.Append("addNamespace(\"" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "\");\r\n");
                sb.Append("addNamespace(\"" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "\");\r\n");
![]() }
            }
![]()
![]() sb.Append(clientNS);
            sb.Append(clientNS);
![]() sb.Append("_class = Class.create();\r\n");
            sb.Append("_class = Class.create();\r\n");
![]()
![]() sb.Append(clientNS);
            sb.Append(clientNS);
![]() sb.Append("_class.prototype = (new AjaxPro.AjaxClass()).extend({\r\n");
            sb.Append("_class.prototype = (new AjaxPro.AjaxClass()).extend({\r\n");
![]()
![]() System.Reflection.MethodInfo method;
            System.Reflection.MethodInfo method;
![]()
![]() for(int y=0; y<mi.Length; y++)
            for(int y=0; y<mi.Length; y++)
![]() {
            {
![]() method = mi[y];
                method = mi[y];
![]()
![]() if(!method.IsPublic)
                if(!method.IsPublic)
![]() continue;
                    continue;
![]()
![]() AjaxNamespaceAttribute[] cmam = (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
                AjaxNamespaceAttribute[] cmam = (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
![]() AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
                AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
![]()
![]() if(ma.Length == 0)
                if(ma.Length == 0)
![]() continue;
                    continue;
![]()
![]() System.Reflection.ParameterInfo[] pi = method.GetParameters();
                System.Reflection.ParameterInfo[] pi = method.GetParameters();
![]()
![]() // Render the function header
                // Render the function header
![]()
![]() sb.Append("\t");
                sb.Append("\t");
![]()
![]() if(cmam.Length == 0)
                if(cmam.Length == 0)
![]() sb.Append(method.Name);
                    sb.Append(method.Name);
![]() else
                else
![]() sb.Append(cmam[0].ClientNamespace);
                    sb.Append(cmam[0].ClientNamespace);
![]()
![]() sb.Append(": function(");
                sb.Append(": function(");
![]()
![]()
![]() // Render all parameters
                // Render all parameters
![]()
![]() for(int i=0; i<pi.Length; i++)
                for(int i=0; i<pi.Length; i++)
![]() {
                {
![]() sb.Append(pi[i].Name);
                    sb.Append(pi[i].Name);
![]()
![]() if(i<pi.Length -1)
                    if(i<pi.Length -1)
![]() sb.Append(", ");
                        sb.Append(", ");
![]() }
                }
![]() 
    
![]() sb.Append(") {\r\n");
                sb.Append(") {\r\n");
![]()
![]()
![]() // Create the XMLHttpRequest object
                // Create the XMLHttpRequest object
![]()
![]() sb.Append("\t\treturn this.invoke(\"" + method.Name + "\", {");        // must be the original method name
                sb.Append("\t\treturn this.invoke(\"" + method.Name + "\", {");        // must be the original method name
![]()
![]() for(int i=0; i<pi.Length; i++)
                for(int i=0; i<pi.Length; i++)
![]() {
                {
![]() sb.Append("\"");
                    sb.Append("\"");
![]() sb.Append(pi[i].Name);
                    sb.Append(pi[i].Name);
![]() sb.Append("\":");
                    sb.Append("\":");
![]() sb.Append(pi[i].Name);
                    sb.Append(pi[i].Name);
![]()
![]() if(i<pi.Length -1)
                    if(i<pi.Length -1)
![]() sb.Append(", ");
                        sb.Append(", ");
![]() }
                }
![]()
![]() sb.Append("}, this.");
                sb.Append("}, this.");
![]() 
                
![]() if(cmam.Length == 0)
                if(cmam.Length == 0)
![]() sb.Append(method.Name);
                    sb.Append(method.Name);
![]() else
                else
![]() sb.Append(cmam[0].ClientNamespace);
                    sb.Append(cmam[0].ClientNamespace);
![]()
![]() sb.Append(".getArguments().slice(");
                sb.Append(".getArguments().slice(");
![]() sb.Append(pi.Length.ToString());
                sb.Append(pi.Length.ToString());
![]() sb.Append("));\r\n\t},\r\n");
                sb.Append("));\r\n\t},\r\n");
![]() }
            }
![]()
![]() string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/") ? "" : "/") + Utility.HandlerPath + "/" + (context.Session != null && context.Session.IsCookieless ? "(" + context.Session.SessionID + ")/" : "") + path + Utility.HandlerExtension;
            string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/") ? "" : "/") + Utility.HandlerPath + "/" + (context.Session != null && context.Session.IsCookieless ? "(" + context.Session.SessionID + ")/" : "") + path + Utility.HandlerExtension;
![]()
![]() sb.Append("\tinitialize: function() {\r\n\t\tthis.url = '" + url + "';\r\n\t}\r\n");
            sb.Append("\tinitialize: function() {\r\n\t\tthis.url = '" + url + "';\r\n\t}\r\n");
![]() sb.Append("});\r\n");
            sb.Append("});\r\n");
![]()
![]()
![]() sb.Append(clientNS);
            sb.Append(clientNS);
![]() sb.Append(" = new ");
            sb.Append(" = new ");
![]() sb.Append(clientNS);
            sb.Append(clientNS);
![]() sb.Append("_class();\r\n");
            sb.Append("_class();\r\n");
![]()
![]()
![]() // save the javascript in current Application context to
            // save the javascript in current Application context to
![]() // speed up the next requests.
            // speed up the next requests.
![]()
![]() // TODO: was knen wir hier machen??
            // TODO: was knen wir hier machen??
![]() // System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
            // System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
![]()
![]() context.Cache.Add(path, new CacheInfo(etag, lastMod), null,
            context.Cache.Add(path, new CacheInfo(etag, lastMod), null, 
![]() System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
![]() System.Web.Caching.CacheItemPriority.Normal, null);
                System.Web.Caching.CacheItemPriority.Normal, null);
![]()
![]() context.Response.Write(sb.ToString());
            context.Response.Write(sb.ToString());
![]() context.Response.Write("\r\n");
            context.Response.Write("\r\n");
![]()
![]() 
            
![]() if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest");
            if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest");
![]() }
        }
代码很明了,只是注释少了点,可能是作者认为没什么难理解的吧,感兴趣的可以到http://www.ajaxpro.info/找源代码跟踪一下,具体的运行过程,可能就更明白是怎么回事了,下篇该来说说这些ashx是用来干什么的了!
核心部分是其web.config配置了httpHandlers 元素
 <httpHandlers>
<httpHandlers> <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/>
      <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/> </httpHandlers>
</httpHandlers>ps:关于httpHandlers的说明可以参看下面几个连接
1.httpHandlers 元素(ASP.NET 设置架构)
2.Microsoft ASP.NET 快速入门教程
3.ASP.NET中的Http Handles
先看看实现IHttpHandlerFactory接口的AjaxHandlerFactory类,只实现了GetHandler方法
其中对core,prototype的处理没什么可说,只是简单的通过EmbeddedJavaScriptHandler的ProcessRequest中将js写入.ashx文件,而converter比较复杂留代下次再做详细分析;这里就重点看看AJAXDemo.Examples.Test.TestMethod,App_Code.urx4hqkg.ashx是怎么来的了;
我跟踪了下代码的运行,在页面加载的时候自定义 HttpHandler 启用 HTTP Web 请求的处理ProcessRequest,也就是进入AjaxHandlerFactory类GetHandler方法的如下入口
 default:
default:
 if(Utility.Settings.UrlNamespaceMappings.Contains(filename))
                            if(Utility.Settings.UrlNamespaceMappings.Contains(filename)) t = Type.GetType(Utility.Settings.UrlNamespaceMappings[filename].ToString());
                                t = Type.GetType(Utility.Settings.UrlNamespaceMappings[filename].ToString());
 if(t == null)
                            if(t == null) t = Type.GetType(filename);
                                t = Type.GetType(filename);
 return new TypeJavaScriptHandler(t);
                            return new TypeJavaScriptHandler(t);TypeJavaScriptHandler也实现了IHttpHandler接口,其ProcessRequest方法如下:
 public void ProcessRequest(HttpContext context)
public void ProcessRequest(HttpContext context) {
        { // The request was not a request to invoke a server-side method.
            // The request was not a request to invoke a server-side method. // Now, we will render the Javascript that will be used on the
            // Now, we will render the Javascript that will be used on the // client to run as a proxy or wrapper for the methods marked
            // client to run as a proxy or wrapper for the methods marked // with the AjaxMethodAttribute.
            // with the AjaxMethodAttribute.
 if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript");
            if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript"); 
         System.Reflection.MethodInfo[] mi = type.GetMethods();
            System.Reflection.MethodInfo[] mi = type.GetMethods(); 
             // Check wether the javascript is already rendered and cached in the
            // Check wether the javascript is already rendered and cached in the // current context.
            // current context. 
             string etag = context.Request.Headers["If-None-Match"];
            string etag = context.Request.Headers["If-None-Match"]; string modSince = context.Request.Headers["If-Modified-Since"];
            string modSince = context.Request.Headers["If-Modified-Since"]; string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
            string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
 if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path))
            if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path)) {
            { foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys)
                foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys) {
                { if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path)
                    if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path) {
                    { path = key;
                        path = key; break;
                        break; }
                    } }
                } }
            }
 if(context.Cache[path] != null)
            if(context.Cache[path] != null) {
            { CacheInfo ci = (CacheInfo)context.Cache[path];
                CacheInfo ci = (CacheInfo)context.Cache[path];
 if(etag != null)
                if(etag != null) {
                { if(etag == ci.ETag)        // TODO: null check
                    if(etag == ci.ETag)        // TODO: null check {
                    { context.Response.StatusCode = 304;
                        context.Response.StatusCode = 304; return;
                        return; }
                    } }
                } 
                 if(modSince != null)
                if(modSince != null) {
                { try
                    try {
                    { DateTime modSinced = Convert.ToDateTime(modSince.ToString()).ToUniversalTime();
                        DateTime modSinced = Convert.ToDateTime(modSince.ToString()).ToUniversalTime(); if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0)
                        if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0) {
                        { context.Response.StatusCode = 304;
                            context.Response.StatusCode = 304; return;
                            return; }
                        } }
                    } catch(Exception)
                    catch(Exception) {
                    { if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "The header value for If-Modified-Since = " + modSince + " could not be converted to a System.DateTime.");
                        if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "The header value for If-Modified-Since = " + modSince + " could not be converted to a System.DateTime."); }
                    } }
                } }
            }
 etag = type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern);
            etag = type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern); etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
            etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
 DateTime now = DateTime.Now;
            DateTime now = DateTime.Now; DateTime lastMod = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
            DateTime lastMod = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
 context.Response.AddHeader("Content-Type", "application/x-javascript");
            context.Response.AddHeader("Content-Type", "application/x-javascript"); context.Response.ContentEncoding = System.Text.Encoding.UTF8;
            context.Response.ContentEncoding = System.Text.Encoding.UTF8; context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
            context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public); context.Response.Cache.SetETag(etag);
            context.Response.Cache.SetETag(etag); context.Response.Cache.SetLastModified(lastMod);
            context.Response.Cache.SetLastModified(lastMod);
 // Ok, we do not have the javascript rendered, yet.
            // Ok, we do not have the javascript rendered, yet. // Build the javascript source and save it to the current
            // Build the javascript source and save it to the current // Application context.
            // Application context.
 System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

 AjaxNamespaceAttribute[] cma = (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
            AjaxNamespaceAttribute[] cma = (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true); string clientNS = type.FullName;
            string clientNS = type.FullName;
 if(cma.Length > 0 && cma[0].ClientNamespace != null)
            if(cma.Length > 0 && cma[0].ClientNamespace != null) {
            { if(cma[0].ClientNamespace.IndexOf(".") > 0)
                if(cma[0].ClientNamespace.IndexOf(".") > 0) sb.Append("addNamespace(\"" + cma[0].ClientNamespace + "\");\r\n");
                    sb.Append("addNamespace(\"" + cma[0].ClientNamespace + "\");\r\n");
 clientNS = cma[0].ClientNamespace;
                clientNS = cma[0].ClientNamespace; }
            } else
            else {
            { sb.Append("addNamespace(\"" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "\");\r\n");
                sb.Append("addNamespace(\"" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "\");\r\n"); }
            }
 sb.Append(clientNS);
            sb.Append(clientNS); sb.Append("_class = Class.create();\r\n");
            sb.Append("_class = Class.create();\r\n");
 sb.Append(clientNS);
            sb.Append(clientNS); sb.Append("_class.prototype = (new AjaxPro.AjaxClass()).extend({\r\n");
            sb.Append("_class.prototype = (new AjaxPro.AjaxClass()).extend({\r\n");
 System.Reflection.MethodInfo method;
            System.Reflection.MethodInfo method;
 for(int y=0; y<mi.Length; y++)
            for(int y=0; y<mi.Length; y++) {
            { method = mi[y];
                method = mi[y];
 if(!method.IsPublic)
                if(!method.IsPublic) continue;
                    continue;
 AjaxNamespaceAttribute[] cmam = (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
                AjaxNamespaceAttribute[] cmam = (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true); AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
                AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
 if(ma.Length == 0)
                if(ma.Length == 0) continue;
                    continue;
 System.Reflection.ParameterInfo[] pi = method.GetParameters();
                System.Reflection.ParameterInfo[] pi = method.GetParameters();
 // Render the function header
                // Render the function header
 sb.Append("\t");
                sb.Append("\t");
 if(cmam.Length == 0)
                if(cmam.Length == 0) sb.Append(method.Name);
                    sb.Append(method.Name); else
                else sb.Append(cmam[0].ClientNamespace);
                    sb.Append(cmam[0].ClientNamespace);
 sb.Append(": function(");
                sb.Append(": function(");

 // Render all parameters
                // Render all parameters
 for(int i=0; i<pi.Length; i++)
                for(int i=0; i<pi.Length; i++) {
                { sb.Append(pi[i].Name);
                    sb.Append(pi[i].Name);
 if(i<pi.Length -1)
                    if(i<pi.Length -1) sb.Append(", ");
                        sb.Append(", "); }
                } 
     sb.Append(") {\r\n");
                sb.Append(") {\r\n");

 // Create the XMLHttpRequest object
                // Create the XMLHttpRequest object
 sb.Append("\t\treturn this.invoke(\"" + method.Name + "\", {");        // must be the original method name
                sb.Append("\t\treturn this.invoke(\"" + method.Name + "\", {");        // must be the original method name
 for(int i=0; i<pi.Length; i++)
                for(int i=0; i<pi.Length; i++) {
                { sb.Append("\"");
                    sb.Append("\""); sb.Append(pi[i].Name);
                    sb.Append(pi[i].Name); sb.Append("\":");
                    sb.Append("\":"); sb.Append(pi[i].Name);
                    sb.Append(pi[i].Name);
 if(i<pi.Length -1)
                    if(i<pi.Length -1) sb.Append(", ");
                        sb.Append(", "); }
                }
 sb.Append("}, this.");
                sb.Append("}, this."); 
                 if(cmam.Length == 0)
                if(cmam.Length == 0) sb.Append(method.Name);
                    sb.Append(method.Name); else
                else sb.Append(cmam[0].ClientNamespace);
                    sb.Append(cmam[0].ClientNamespace);
 sb.Append(".getArguments().slice(");
                sb.Append(".getArguments().slice("); sb.Append(pi.Length.ToString());
                sb.Append(pi.Length.ToString()); sb.Append("));\r\n\t},\r\n");
                sb.Append("));\r\n\t},\r\n"); }
            }
 string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/") ? "" : "/") + Utility.HandlerPath + "/" + (context.Session != null && context.Session.IsCookieless ? "(" + context.Session.SessionID + ")/" : "") + path + Utility.HandlerExtension;
            string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/") ? "" : "/") + Utility.HandlerPath + "/" + (context.Session != null && context.Session.IsCookieless ? "(" + context.Session.SessionID + ")/" : "") + path + Utility.HandlerExtension;
 sb.Append("\tinitialize: function() {\r\n\t\tthis.url = '" + url + "';\r\n\t}\r\n");
            sb.Append("\tinitialize: function() {\r\n\t\tthis.url = '" + url + "';\r\n\t}\r\n"); sb.Append("});\r\n");
            sb.Append("});\r\n");

 sb.Append(clientNS);
            sb.Append(clientNS); sb.Append(" = new ");
            sb.Append(" = new "); sb.Append(clientNS);
            sb.Append(clientNS); sb.Append("_class();\r\n");
            sb.Append("_class();\r\n");

 // save the javascript in current Application context to
            // save the javascript in current Application context to // speed up the next requests.
            // speed up the next requests.
 // TODO: was knen wir hier machen??
            // TODO: was knen wir hier machen?? // System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
            // System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
 context.Cache.Add(path, new CacheInfo(etag, lastMod), null,
            context.Cache.Add(path, new CacheInfo(etag, lastMod), null,  System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
                System.Web.Caching.CacheItemPriority.Normal, null);
 context.Response.Write(sb.ToString());
            context.Response.Write(sb.ToString()); context.Response.Write("\r\n");
            context.Response.Write("\r\n");
 
             if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest");
            if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest"); }
        }代码很明了,只是注释少了点,可能是作者认为没什么难理解的吧,感兴趣的可以到http://www.ajaxpro.info/找源代码跟踪一下,具体的运行过程,可能就更明白是怎么回事了,下篇该来说说这些ashx是用来干什么的了!
 
                    
                     
                    
                 
                    
                 
        
 
             
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号