【AjaxPro实现机制浅析二】*.ashx文件是怎么来的?

上篇 说到AjaxPro为我们生成了四个ashx文件来达到异步调用的目的,这次呢,就说说这些ashx文件是怎么生成的;

核心部分是其web.config配置了httpHandlers 元素
None.gif < httpHandlers >
None.gif      
< add verb = " POST,GET "  path = " ajaxpro/*.ashx "  type = " AjaxPro.AjaxHandlerFactory, AjaxPro " />
None.gif
</ 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方法的如下入口
None.gif default :
None.gif
None.gif                            
if (Utility.Settings.UrlNamespaceMappings.Contains(filename))
None.gif                                t 
=  Type.GetType(Utility.Settings.UrlNamespaceMappings[filename].ToString());
None.gif
None.gif                            
if (t  ==   null )
None.gif                                t 
=  Type.GetType(filename);
None.gif
None.gif                            
return   new  TypeJavaScriptHandler(t);

TypeJavaScriptHandler也实现了IHttpHandler接口,其ProcessRequest方法如下:
None.gif public   void  ProcessRequest(HttpContext context)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
// The request was not a request to invoke a server-side method.
InBlock.gif            
// Now, we will render the Javascript that will be used on the
InBlock.gif            
// client to run as a proxy or wrapper for the methods marked
InBlock.gif            
// with the AjaxMethodAttribute.
InBlock.gif

InBlock.gif            
if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript");
InBlock.gif        
InBlock.gif            System.Reflection.MethodInfo[] mi 
= type.GetMethods();
InBlock.gif            
InBlock.gif            
// Check wether the javascript is already rendered and cached in the
InBlock.gif            
// current context.
InBlock.gif
            
InBlock.gif            
string etag = context.Request.Headers["If-None-Match"];
InBlock.gif            
string modSince = context.Request.Headers["If-Modified-Since"];
InBlock.gif            
string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
InBlock.gif
InBlock.gif            
if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        path 
= key;
InBlock.gif                        
break;
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
if(context.Cache[path] != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                CacheInfo ci 
= (CacheInfo)context.Cache[path];
InBlock.gif
InBlock.gif                
if(etag != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if(etag == ci.ETag)        // TODO: null check
ExpandedSubBlockStart.gifContractedSubBlock.gif
                    dot.gif{
InBlock.gif                        context.Response.StatusCode 
= 304;
InBlock.gif                        
return;
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
InBlock.gif                
if(modSince != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        DateTime modSinced 
= Convert.ToDateTime(modSince.ToString()).ToUniversalTime();
InBlock.gif                        
if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            context.Response.StatusCode 
= 304;
InBlock.gif                            
return;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
catch(Exception)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
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.");
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            etag 
= type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern);
InBlock.gif
            etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
InBlock.gif
InBlock.gif            DateTime now 
= DateTime.Now;
InBlock.gif            DateTime lastMod 
= new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
InBlock.gif

InBlock.gif            context.Response.AddHeader(
"Content-Type""application/x-javascript");
InBlock.gif            context.Response.ContentEncoding 
= System.Text.Encoding.UTF8;
InBlock.gif            context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
InBlock.gif            context.Response.Cache.SetETag(etag);
InBlock.gif            context.Response.Cache.SetLastModified(lastMod);
InBlock.gif
InBlock.gif            
// Ok, we do not have the javascript rendered, yet.
InBlock.gif            
// Build the javascript source and save it to the current
InBlock.gif            
// Application context.
InBlock.gif

InBlock.gif            System.Text.StringBuilder sb 
= new System.Text.StringBuilder();
InBlock.gif
InBlock.gif
InBlock.gif            AjaxNamespaceAttribute[] cma 
= (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
InBlock.gif            
string clientNS = type.FullName;
InBlock.gif
InBlock.gif            
if(cma.Length > 0 && cma[0].ClientNamespace != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if(cma[0].ClientNamespace.IndexOf("."> 0)
InBlock.gif                    sb.Append(
"addNamespace(\"" + cma[0].ClientNamespace + "\");\r\n");
InBlock.gif
InBlock.gif                clientNS 
= cma[0].ClientNamespace;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                sb.Append(
"addNamespace(\"" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "\");\r\n");
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            sb.Append(clientNS);
InBlock.gif            sb.Append(
"_class = Class.create();\r\n");
InBlock.gif
InBlock.gif            sb.Append(clientNS);
InBlock.gif            sb.Append(
"_class.prototype = (new AjaxPro.AjaxClass()).extend({\r\n");
InBlock.gif
InBlock.gif            System.Reflection.MethodInfo method;
InBlock.gif
InBlock.gif            
for(int y=0; y<mi.Length; y++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                method 
= mi[y];
InBlock.gif
InBlock.gif                
if(!method.IsPublic)
InBlock.gif                    
continue;
InBlock.gif
InBlock.gif                AjaxNamespaceAttribute[] cmam 
= (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
InBlock.gif                AjaxMethodAttribute[] ma 
= (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
InBlock.gif
InBlock.gif                
if(ma.Length == 0)
InBlock.gif                    
continue;
InBlock.gif
InBlock.gif                System.Reflection.ParameterInfo[] pi 
= method.GetParameters();
InBlock.gif
InBlock.gif                
// Render the function header
InBlock.gif

InBlock.gif                sb.Append(
"\t");
InBlock.gif
InBlock.gif                
if(cmam.Length == 0)
InBlock.gif                    sb.Append(method.Name);
InBlock.gif                
else
InBlock.gif                    sb.Append(cmam[
0].ClientNamespace);
InBlock.gif
InBlock.gif                sb.Append(
": function(");
InBlock.gif
InBlock.gif
InBlock.gif                
// Render all parameters
InBlock.gif

InBlock.gif                
for(int i=0; i<pi.Length; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    sb.Append(pi[i].Name);
InBlock.gif
InBlock.gif                    
if(i<pi.Length -1)
InBlock.gif                        sb.Append(
"");
ExpandedSubBlockEnd.gif                }

InBlock.gif    
InBlock.gif                sb.Append(
") {\r\n");
InBlock.gif
InBlock.gif
InBlock.gif                
// Create the XMLHttpRequest object
InBlock.gif

InBlock.gif                sb.Append(
"\t\treturn this.invoke(\"" + method.Name + "\", {");        // must be the original method name
InBlock.gif

InBlock.gif                
for(int i=0; i<pi.Length; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    sb.Append(
"\"");
InBlock.gif
                    sb.Append(pi[i].Name);
InBlock.gif                    sb.Append(
"\":");
InBlock.gif
                    sb.Append(pi[i].Name);
InBlock.gif
InBlock.gif                    
if(i<pi.Length -1)
InBlock.gif                        sb.Append(
"");
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                sb.Append(
"}, this.");
InBlock.gif                
InBlock.gif                
if(cmam.Length == 0)
InBlock.gif                    sb.Append(method.Name);
InBlock.gif                
else
InBlock.gif                    sb.Append(cmam[
0].ClientNamespace);
InBlock.gif
InBlock.gif                sb.Append(
".getArguments().slice(");
InBlock.gif                sb.Append(pi.Length.ToString());
InBlock.gif                sb.Append(
"));\r\n\t},\r\n");
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/"? "" : "/"+ Utility.HandlerPath + "/" + (context.Session != null && context.Session.IsCookieless ? "(" + context.Session.SessionID + ")/" : ""+ path + Utility.HandlerExtension;
InBlock.gif
InBlock.gif            sb.Append(
"\tinitialize: function() {\r\n\t\tthis.url = '" + url + "';\r\n\t}\r\n");
InBlock.gif            sb.Append(
"});\r\n");
InBlock.gif
InBlock.gif
InBlock.gif            sb.Append(clientNS);
InBlock.gif            sb.Append(
" = new ");
InBlock.gif            sb.Append(clientNS);
InBlock.gif            sb.Append(
"_class();\r\n");
InBlock.gif
InBlock.gif
InBlock.gif            
// save the javascript in current Application context to
InBlock.gif            
// speed up the next requests.
InBlock.gif
InBlock.gif            
// TODO: was knen wir hier machen??
InBlock.gif            
// System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
InBlock.gif

InBlock.gif            context.Cache.Add(path, 
new CacheInfo(etag, lastMod), null
InBlock.gif                System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
InBlock.gif                System.Web.Caching.CacheItemPriority.Normal, 
null);
InBlock.gif
InBlock.gif            context.Response.Write(sb.ToString());
InBlock.gif            context.Response.Write(
"\r\n");
InBlock.gif
InBlock.gif            
InBlock.gif            
if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest");
ExpandedBlockEnd.gif        }

代码很明了,只是注释少了点,可能是作者认为没什么难理解的吧,感兴趣的可以到 http://www.ajaxpro.info/找源代码跟踪一下,具体的运行过程,可能就更明白是怎么回事了,下篇该来说说这些ashx是用来干什么的了!

转载于:https://www.cnblogs.com/Hedonister/archive/2006/03/21/354887.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值