在写这篇随笔之前,其实网上早已有高手分析了.text的urlrewrite的实现(点击这里查看全文),问题是作为一个初学者的我,看了以后,感觉没有切中要害。所以,产生了写这篇dd的冲动。

从头说起,.text是通过httpModules和httpHandlers来实现urlrewrite的,看看web.config中的配置
 1.Text(博客园)Url rewrite详细分析        <httpHandlers>
 2.Text(博客园)Url rewrite详细分析            <!-- Can not see to load asmx like .aspx, since we will grap all requests later, make sure these are processed by their default factory -->
 3.Text(博客园)Url rewrite详细分析            <add verb="*" path="*.asmx" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
 4.Text(博客园)Url rewrite详细分析                validate="false" />
 5.Text(博客园)Url rewrite详细分析            <!--Since we are grabbing all requests after this, make sure Error.aspx does not rely on .Text -->
 6.Text(博客园)Url rewrite详细分析            <add verb="*" path="Error.aspx" type="System.Web.UI.PageHandlerFactory" />
 7.Text(博客园)Url rewrite详细分析            <!--This will process any ext mapped to aspnet_isapi.dll -->
 8.Text(博客园)Url rewrite详细分析            <add verb="*" path="*" type="Dottext.Common.UrlManager.UrlReWriteHandlerFactory,Dottext.Common" />
 9.Text(博客园)Url rewrite详细分析        </httpHandlers>
10.Text(博客园)Url rewrite详细分析        <httpModules>
11.Text(博客园)Url rewrite详细分析            <add name="UrlReWriteModule" type="Dottext.Common.UrlManager.UrlReWriteModule, Dottext.Common" />
12.Text(博客园)Url rewrite详细分析            <add name="EventHttpModule" type="Dottext.Framework.ScheduledEvents.EventHttpModule, Dottext.Framework" />
13.Text(博客园)Url rewrite详细分析            <!--<add name="MsftBlogsHttpModule" type= "AspNetWeb.MsftBlogsHttpModule, MsftBlogsHttpModule" />-->
14.Text(博客园)Url rewrite详细分析        </httpModules>
15.Text(博客园)Url rewrite详细分析

看看第11行,配置了Dottext.Common.UrlManager.UrlReWriteModule这个httpModule,很显然,从名字来看,它就是实现urlrewrite功能的httpmodule,去看看它的源代码
 1.Text(博客园)Url rewrite详细分析        static UrlReWriteModule()
 2

代码有点长,不过没关系,结构还是很清晰的。用户发出的url请求,在context_BeginRequest中进行了第一次过滤,这个函数把url做了一下归整,判断来自用户的请求是 应用程序根目录下的.aspx文件,如果是则不进行urlrewrite(由UrlHelper.SetEnableUrlReWriting这个函数进行设置)。什么?看不懂regexPath = new Regex(@"^/?(\w|-|_)+\.aspx$",……); 这句话?建议你去看一下正则表达式,这里的意思是指,需要匹配的字符串所对应的文件是否在根目录下,举例来说,
/contact.aspx
default.aspx
匹配,而
 /oop80/default.aspx
则不匹配,
总而言之,context_BeginRequest函数把对根目录下.aspx文件的请求,以及webservice,设置成不需要进行urlrewrite,其余的,则需要进行下一步的处理,在什么地方处理呢,我们来看看web.config中的配置,第8行,很清晰的告诉我们,在Dottext.Common.UrlManager.UrlReWriteHandlerFactory中,会对用户的请求做进一步分析和处理。 来看看源代码

 1.Text(博客园)Url rewrite详细分析public class UrlReWriteHandlerFactory:  IHttpHandlerFactory
 2

代码很长,但是它是实现urlrewrite的关键,我们来分析分析看。
UrlReWriteHandlerFactory实现了IHttpHandlerFactory接口,而IHttpHandlerFactory最关键的地方在于GetHandler这个函数接口,所以我们从GetHandler函数入手。
首先是 HttpHandler [] items = GetHttpHandlers(context); 通过查看GetHttpHandlers的定义,可以得知返回的其实是HandlerConfiguration中一个叫HttpHandlers的属性,它的值,是通过这么一句话来进行初始化的,return ((HandlerConfiguration)ConfigurationSettings.GetConfig("HandlerConfiguration")); 想必大家现在都明白了,HandlerConfiguration对象是通过将web.config中<HandlerConfiguration>节进行反序列化获得的,关于ConfigurationSettings.GetConfig的使用,网上已经有很多了,在这里就不重复劳动了。看看web.config中的HandlerConfiguration节
 1.Text(博客园)Url rewrite详细分析    <HandlerConfiguration defaultPageLocation="default.aspx" type="Dottext.Common.UrlManager.HandlerConfiguration, Dottext.Common">
 2.Text(博客园)Url rewrite详细分析        <HttpHandlers>
 3.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="(\.config|\.asax|\.ascx|\.config|\.cs|\.vb|\.vbproj|\.asp|\.licx|\.resx|\.resources)$"    type="Dottext.Framework.UrlManager.HttpForbiddenHandler, Dottext.Framework" handlerType="Direct" />
 4.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="(\.gif|\.js|\.jpg|\.zip|\.jpeg|\.jpe|\.css|\.rar|\.xml|\.xsl)$" type="Dottext.Common.UrlManager.BlogStaticFileHandler, Dottext.Common" handlerType="Direct" />
 5.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/rss\.aspx$" type="Dottext.Common.Syndication.RssHandler, Dottext.Common"    handlerType="Direct" />
 6.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/CommentsRSS\.aspx$" type="Dottext.Common.Syndication.RecentCommentsRSS, Dottext.Common" handlerType="Direct" />
 7.Text(博客园)Url rewrite详细分析            <HttpHandler pattern = "/RecentCommentsRSS\.aspx$" type = "Dottext.Common.Syndication.RecentCommentsRSS, Dottext.Common" handlerType = "Direct" />
 8.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/atom\.aspx$" type="Dottext.Common.Syndication.AtomHandler, Dottext.Common" handlerType="Direct" />
 9.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/comments/commentRss/\d+\.aspx$" type="Dottext.Common.Syndication.RssCommentHandler, Dottext.Common" handlerType="Direct" />
10.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/aggbug/\d+\.aspx$" type="Dottext.Framework.Tracking.AggBugHandler, Dottext.Framework" handlerType="Direct" />
11.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/customcss\.aspx$" type="Dottext.Web.UI.Handlers.BlogSecondaryCssHandler, Dottext.Web" handlerType="Direct" />
12.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/category\/(\d|\w|\s)+\.aspx/rss$" type="Dottext.Common.Syndication.RssCategoryHandler, Dottext.Common" handlerType="Direct" />
13.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/favorite\/(\d|\w|\s)+\.aspx/rss$" type="Dottext.Common.Syndication.RssLinksHandler, Dottext.Common" handlerType="Direct" />
14.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/articles/\d+\.aspx$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
15.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/articles/\w+\.aspx$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
16.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/PreviewPost.aspx$" controls="PreviewPost.ascx" />
17.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/archive/\d{4}/\d{2}/\d{2}/\d+\.(aspx|htm)$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
18.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/archive/\d{4}/\d{2}/\d{2}/\w+\.(aspx|htm)$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
19.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/archive/\d{4}/\d{1,2}/\d{1,2}\.aspx$" controls="ArchiveDay.ascx" />
20.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/archive/\d{4}/\d{1,2}\.aspx$" controls="ArchiveMonth.ascx" />
21.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/archives/\d{4}/\d{1,2}\.aspx$" controls="ArticleArchiveMonth.ascx" />
22.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/contact\.aspx$" controls="Contact.ascx" />
23.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/AddToFavorite\.aspx$" handlerType="Page" pageLocation="AddToFavorite.aspx" />
24.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/BlogSearch\.aspx$" controls="BlogSearch.ascx" />
25.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/posts/|/story/|/archive/" type="Dottext.Web.UI.Handlers.RedirectHandler,Dottext.Web"    handlerType="Direct" />
26.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/gallery\/\d+\.aspx$" controls="GalleryThumbNailViewer.ascx" />
27.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/gallery\/image\/\d+\.aspx$" controls="ViewPicture.ascx" />
28.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/(?:category|stories)/(\w|\s)+\.aspx$" controls="CategoryEntryList.ascx" />
29.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/favorite/(\w|\s)+\.aspx$" controls="FavoriteList.ascx" />
30.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/(?:admin)" type="Dottext.Web.UI.Handlers.BlogExistingPageHandler, Dottext.Web" handlerType="Factory" />
31.Text(博客园)Url rewrite详细分析            <!--<HttpHandler pattern = "^(?:\/(\w|\s|\.(?!aspx))+((\/login\.aspx)?|(\/?))?)$" type = "Dottext.Web.UI.Handlers.BlogExistingPageHandler, Dottext.Web" handlerType = "Factory" />-->
32.Text(博客园)Url rewrite详细分析            <!--<HttpHandler pattern = "^(?:/\w+\/(\w|\s|\.)+\/(?:admin|logout\.aspx|login\.aspx))" type = "Dottext.Web.UI.Handlers.BlogExistingPageHandler, Dottext.Web" handlerType = "Factory" />-->
33.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/comments\/\d+\.aspx$" type="Dottext.Common.Syndication.CommentHandler, Dottext.Common" handlerType="Direct" />
34.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/services\/trackbacks/\d+\.aspx$" type="Dottext.Framework.Tracking.TrackBackHandler, Dottext.Framework" handlerType="Direct" />
35.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/services\/pingback\.aspx$" type="Dottext.Framework.Tracking.PingBackService, Dottext.Framework"    handlerType="Direct" />
36.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/services\/metablogapi\.aspx$" type="Dottext.Framework.XmlRpc.MetaWeblog, Dottext.Framework"    handlerType="Direct" />
37.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="/Services\/SyncHanlder\.aspx$" handlerType="Page" pageLocation="Sevices/DottextAPI.aspx" />
38.Text(博客园)Url rewrite详细分析            <!-- 只显示文章标题列表 -->
39.Text(博客园)Url rewrite详细分析            <!--<HttpHandler pattern="^((/default\.aspx)|(/)|(/index\.aspx))$" controls="CategoryPostsList.ascx" />-->
40.Text(博客园)Url rewrite详细分析            <!-- 显示文章内容 -->
41.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="^((/default\.aspx)|(/)|(/index\.aspx))$" controls="PagedPosts.ascx" />
42.Text(博客园)Url rewrite详细分析            <HttpHandler pattern="^(/posts\.aspx)$" controls="PagedPosts.ascx" />
43.Text(博客园)Url rewrite详细分析            <!--<HttpHandler pattern = "/services/\w+.asmx$" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"  handlerType = "Factory" />-->
44.Text(博客园)Url rewrite详细分析            <HttpHandler pattern = "^(?:\/(\w|\s|\.(?!aspx))+((\/default\.aspx)?|(\/?))?)$"  controls = "homepage.ascx"/>
45.Text(博客园)Url rewrite详细分析            <!--<HttpHandler pattern="^(?:/\w+\/(\w|\s|\.(?!aspx))+((\/default\.aspx)?|(\/?))?)$" controls="homepage.ascx" />-->
46.Text(博客园)Url rewrite详细分析            
47.Text(博客园)Url rewrite详细分析        </HttpHandlers>
48.Text(博客园)Url rewrite详细分析    </HandlerConfiguration>
49.Text(博客园)Url rewrite详细分析

其实在visual studio.net中看这段代码会更加清楚一点,这里的每一个pattern其实都会建立对应的Regex ,来对用户请求的url进行匹配,下面的代码会很详细说明这一点,我们往下看。

接下来是一个循环,循环中执行这么一句话
if (items[i].IsMatch(Dottext.Framework.Util.Globals.RemoveAppFromPath(context.Request.Path,context.Request.ApplicationPath))) {...}
它把web.config中每一个httphandler来匹配用户的请求,IsMatch函数中会根据pattern建立相应的Regex,并调用Regex.IsMatch函数,如果请求匹配该pattern,则调用对应的模块来进行处理。很显然,这里是实现urlrewrite的关键之处,比如,请求的是这么一个url 
http://oop80.cnblogs.com/archive/2005/08/09/210550.html
那么,他就会匹配这一个handler
<HttpHandler pattern="/archive/\d{4}/\d{2}/\d{2}/\d+\.(aspx|htm)$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
那么,程序就会调用 viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx 来处理用户的请求,
又如,请求这么一个url
http://oop80.cnblogs.com/category/23435.aspx
匹配
<HttpHandler pattern="/(?:category|stories)/(\w|\s)+\.aspx$" controls="CategoryEntryList.ascx" />

最后程序是一个switch语句,根据handlertype的不同进行各种处理,具体就不在解释了,因为……这一段我自己也没有进行更深入一步的研究,里面还有一些细节,如SetControls的控件在什么地方载入,GetCompiledPageInstance函数的具体用法等等。不过,这些东西终归和urlrewrite没多大关系了,不在我们讨论的范围之内。

请大家多多指教,谢谢

相关文章:

  • 2021-08-11
  • 2022-02-01
  • 2021-08-26
  • 2022-12-23
  • 2022-12-23
  • 2021-11-17
  • 2022-12-23
猜你喜欢
  • 2021-05-28
  • 2021-11-22
  • 2021-06-28
  • 2021-12-06
  • 2021-07-05
  • 2022-12-23
  • 2021-08-30
相关资源
相似解决方案