.text urlRewrite介绍。。

1、花絮:
第一次拿到dottext时,开始让我比较觉得比较奇怪的是

一、以floerggyy注册后通过URL:http://x.x.x.x/floerggyy即可进入自己的blog里
(其实忘了以前常做下载页面download.aspx也不过是处理了HttpHandler的虚页面而已,可能是见在.Text兴奋的连这些基本常识都忘了^_^)

二、居然可以拿用户名做用户的唯一标识但在表里面没有找到做为用户名UserName唯一约束的东东(到现在还不清楚在数据库哪个地方设置的,有知道的请指点下)
后来通过重得注册同一用户名查看抛出的异常信息,确认确实在有UserName做为唯一约束的东东。
唉,看来我对数据库一无所知。


...后来决定专写一篇关于URL重写的文章,后来看到dottext的原作者也简单介绍了下urlRewrite,于是这个想法就放弃了。
后来又有一些朋友问dottext关于URL的问题,看来还是写吧

2、配置文件WebConfig.config简单浏览

None.gif 自定义配置节内容:
None.gif 
< configSections >
None.gif  
< section  name ="BlogConfigurationSettings"  type ="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework"   />
None.gif  
< section  name ="HandlerConfiguration"  type ="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework"   />
None.gif  
< section  name ="SearchConfiguration"  type ="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework"   />
None.gif  
< section  name ="microsoft.web.services"  type ="Microsoft.Web.Services.Configuration.WebServicesConfiguration, Microsoft.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"   />
None.gif  
< section  name ="codeHighlighter"  type ="ActiproSoftware.CodeHighlighter.CodeHighlighterConfigurationSectionHandler, ActiproSoftware.CodeHighlighter"   />
None.gif 
</ configSections >
None.gif
None.gifHttpHandler的配置内容:
None.gif 
< httpHandlers >
None.gif  
< add  verb ="*"  path ="*.asmx"  type ="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
None.gif   validate
="false"   />
None.gif  
< add  verb ="*"  path ="Error.aspx"  type ="System.Web.UI.PageHandlerFactory"   />
None.gif  
< add  verb ="*"  path ="*"  type ="Dottext.Common.UrlManager.UrlReWriteHandlerFactory,Dottext.Common"   />
None.gif 
</ httpHandlers >
None.gif
None.gifHttpModule的配置内容:
None.gif 
< httpModules >
None.gif  
< add  name ="UrlReWriteModule"  type ="Dottext.Common.UrlManager.UrlReWriteModule, Dottext.Common"   />
None.gif  
< add  name ="EventHttpModule"  type ="Dottext.Framework.ScheduledEvents.EventHttpModule, Dottext.Framework"   />
None.gif 
</ httpModules >
None.gif
None.gif


见到一个陌生的项目首先打开它的配置文件看看,这是我的习惯:)
先看看一些重点的配置内容:

看完Web.config中的上述内容熟悉asp.net运行机制的朋友就明白,DotText代码的运行顺序。在这里我再简单重复下
aspnet的内部运行机制(若有不熟悉的朋友请参阅<<ASP.NET FameWork深度历险>>这本书,它对做asp.net开发的朋友很有帮助):
remote client Request---->IIS---->aspnet_isapi.dll-->aspnet_wp.exe-->HttpRuntime--->
HttpModule--->HttpHandler Factory--->HttpHandler--->HttpHandler.ProcessRequest()-->Response client Request

好了,题归正转,client Request首先是被HttpModule截获。当我们请求.text的URL:http://www.cnblogs.com/floerggyy/时,首先是
Dottext.Common.UrlManager命名空间下类UrlReWriteModule的相关方法被调用。
(为什么会被类UrlReWriteModule截获远程请求呢?上面HttpModule配置节的内容不是标明了吗???^_^
明知故问,那么为Dottext.Framework.ScheduledEvents命名空间下的类EventHttpModule会不会截获远程请求?什么时候截获呢?
当然是按先来后顺序了,中国的优良传统都忘了!!!
(其实这样说也是不太准确的,这两个HttpModule确是按顺序执行的但在HttpModule里的一些事件中它们是交叉运行的,好了类EventHttpModule
不在我们的计论范围内在下面的代码就不分析了,有对这块不明白的最好去看下上面推荐的那本书^_^)

3 、URL重写,部分代码分析(这块涉及到众多自定义配置节、HttpModule、HttpHandler的综合应用所以要理顺还是有点麻烦的,要有一小点分析别人代码的耐心。个人认为emwink.gif)

类UrlReWriteModule的方法

ExpandedBlockStart.gif ContractedBlock.gif private   void  context_BeginRequest( object  sender, EventArgs e) dot.gif {
InBlock.gif
//它是主要作用是根据请求匹配正则表达式来设置是否重写客户所请求的URL(它默认是重写URL),注意这句代码UrlHelper.SetEnableUrlReWriting(context,false);
ExpandedSubBlockStart.gifContractedSubBlock.gif
 if(ConfigProvider.Instance().IsAggregateSite)dot.gif{
InBlock.gif    HttpContext context  
= ((HttpApplication)sender).Context;
InBlock.gif
InBlock.gif    
string path = context.Request.Path.ToLower();
InBlock.gif    
int iExtraStuff = path.IndexOf(".aspx");
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if(iExtraStuff > -1 || path.IndexOf("."== -1dot.gif{
InBlock.gif     
if(iExtraStuff > -1)
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{
InBlock.gif      path 
= path.Remove(iExtraStuff+5,path.Length - (iExtraStuff+5));
ExpandedSubBlockEnd.gif     }

InBlock.gif
InBlock.gif     path 
= regexApplication.Replace(path,string.Empty,1,0);
InBlock.gif
InBlock.gif     
if(path == "" || path == "/"  || regexPath.IsMatch(path))
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{
InBlock.gif      UrlHelper.SetEnableUrlReWriting(context,
false);
ExpandedSubBlockEnd.gif     }

InBlock.gif     
ExpandedSubBlockEnd.gif    }
else if(context.Request.Path.ToLower().IndexOf("services"> 0 && context.Request.Path.ToLower().IndexOf(".asmx"> 0 )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif     
if(AlllowService(context))
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{
InBlock.gif      
if(context.Request.RequestType!="POST")
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif       
string regexstr=@"/\w+/services/";
InBlock.gif       
string url=Regex.Replace(context.Request.RawUrl,regexstr,"/services/",RegexOptions.IgnoreCase);
InBlock.gif       context.RewritePath(url);
ExpandedSubBlockEnd.gif      }

InBlock.gif      
//string fileName =context.Request; //System.IO.Path.GetFileName(context.Request.Path);
InBlock.gif      
//context.RewritePath("~/Services/" + fileName);
ExpandedSubBlockStart.gifContractedSubBlock.gif
     }
elsedot.gif{
InBlock.gif      context.Response.Clear();
InBlock.gif      context.Response.End();
ExpandedSubBlockEnd.gif     }

ExpandedSubBlockEnd.gif    }

InBlock.gif   
ExpandedSubBlockEnd.gif   }

InBlock.gif
InBlock.gif


HttpModule处理完后(这句话并不正确,在这里是这样的)进入HttpHandler Factory,根据HttpHandler的配置内容我们可以马上找到这个类
UrlReWriteHandlerFactory它是处理重写URL请求核心,在这里我详细分析下。
它实现了IHttpHandlerFactory
(看注释就知道这个类是很重要的了24.gif)

None.gif using  System;
None.gif
using  System.Web;
None.gif
using  System.Web.UI;
None.gif
using  System.Text.RegularExpressions;
None.gif
None.gif
using  Dottext.Framework;
None.gif
using  Dottext.Framework.Components;
None.gif
using  Dottext.Framework.Configuration;
None.gif
None.gif
namespace  Dottext.Common.UrlManager
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Class responisble for figuring out which .Text page to load. By default will load an array of Dottext.UrlManager.HttpHanlder
InBlock.gif    
/// from the blog.config file. This contains a list of Regex patterns to match the current request to. It also allows caching of the 
InBlock.gif    
/// Regex's and Types
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class UrlReWriteHandlerFactory:  IHttpHandlerFactory
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public UrlReWriteHandlerFactory()dot.gif{} //Nothing to do in the cnstr
InBlock.gif
        //自定义虚方法从自定义配置节内容反序列化时构造Httphandler
InBlock.gif        
protected virtual HttpHandler[] GetHttpHandlers(HttpContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return HandlerConfiguration.Instance().HttpHandlers;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// Implementation of IHttpHandlerFactory. By default, it will load an array of HttpHanlder (Dottext.UrlManager.HttpHandler) from
InBlock.gif        
/// the blog.config. This can be changed, by overrideing the GetHttpHandlers(HttpContext context) method. 
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="context">Current HttpContext</param>
InBlock.gif        
/// <param name="requestType">Request Type (Passed along to other IHttpHandlerFactory's)</param>
InBlock.gif        
/// <param name="url">The current requested url. (Passed along to other IHttpHandlerFactory's)</param>
InBlock.gif        
/// <param name="path">The physical path of the current request. Is not gaurenteed to exist (Passed along to other IHttpHandlerFactory's)</param>
InBlock.gif        
/// <returns>
InBlock.gif        
/// Returns an Instance of IHttpHandler either by loading an instance of IHttpHandler or by returning an other
InBlock.gif        
/// IHttpHandlerFactory.GetHanlder(HttpContext context, string requestType, string url, string path) method
ExpandedSubBlockEnd.gif        
/// </returns>
         //实现接口IHttpHandlerFactory定义的方法
InBlock.gif        public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string path)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//Get the Handlers to process. By defualt, we grab them from the blog.config
InBlock.gif
            HttpHandler[] items = GetHttpHandlers(context);
InBlock.gif            
//Dottext.Framework.Logger.LogManager.Log("path",Dottext.Framework.Util.Globals.RemoveAppFromPath(context.Request.Path,context.Request.ApplicationPath));
InBlock.gif            
//Do we have any?
InBlock.gif
            if(items != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
int count = items.Length;
InBlock.gif
InBlock.gif                
for(int i = 0; i<count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
//We should use our own cached Regex. This should limit the number of Regex's created
InBlock.gif                    
//and allows us to take advantage of RegexOptons.Compiled 
InBlock.gif
                    //逐个匹配所配置节中定义的请求类型
InBlock.gif                    
if(items[i].IsMatch(Dottext.Framework.Util.Globals.RemoveAppFromPath(context.Request.Path,context.Request.ApplicationPath)))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                       //注意这里是关键,注意返回的Httphandler实例
                            //throw new Exception();
InBlock.gif
                        switch(items[i].HandlerType)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            
case HandlerType.Page://默认是Page
InBlock.gif
                                                        
InBlock.gif                                
return ProccessHandlerTypePage(items[i],context,requestType,url);
InBlock.gif                            
case HandlerType.Direct:
InBlock.gif                                HandlerConfiguration.SetControls(context,items[i].BlogControls);
InBlock.gif                                
return (IHttpHandler)items[i].Instance();
InBlock.gif                            
case HandlerType.Factory:
InBlock.gif                                
//Pass a long the request to a custom IHttpHandlerFactory
InBlock.gif
                                return ((IHttpHandlerFactory)items[i].Instance()).GetHandler(context,requestType,url,path);
InBlock.gif                            
default:
InBlock.gif                                
throw new Exception("Invalid HandlerType: Unknown");
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
//If we do not find the page, just let ASP.NET take over
InBlock.gif
            return PageHandlerFactory.GetHandler(context,requestType,url, path);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif        
private IHttpHandler ProccessHandlerTypePage(HttpHandler item, HttpContext context, string requestType, string url)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string pagepath = item.FullPageLocation;
InBlock.gif            
if(pagepath == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                pagepath 
= HandlerConfiguration.Instance().FullPageLocation;
ExpandedSubBlockEnd.gif            }

InBlock.gif            HandlerConfiguration.SetControls(context,item.BlogControls);
InBlock.gif            IHttpHandler myhandler
=PageParser.GetCompiledPageInstance(url,pagepath,context);
InBlock.gif            
return myhandler;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif        
public virtual void ReleaseHandler(IHttpHandler handler) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

要注意它是如何把自定义配置节中的内容拈合成httphandler的实例
把这些理顺后对于理解.text的url重写就不难了emwink.gif24.gif....

对上面若有理解不正解的欢迎高手指正

 

P.S.
由于本人对opensource的认识不够才导致昨天的冒失之笔---对众多开源项目发些牢骚.......http://www.cnblogs.com/floerggyy/archive/2005/01/11/90108.html
在些,再次感谢rIPPERsighcessk等朋友批正

既然问题是我首先提出的,那就让我为这些开源项目尽点微薄之力吧

哪些朋友有对一些开源项目中引用的第三方组件不清楚的,请回那篇贴子,我统一整理下并公布出来75_75.gif75_75.gif75_75.gif

 

 

 


 

转载于:https://www.cnblogs.com/floerggyy/archive/2005/01/12/90556.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值