1、花絮: 
第一次拿到dottext時(shí),開始讓我比較覺得比較奇怪的是 
一、以floerggyy注冊后通過url:http://x.x.x.x/floerggyy即可進(jìn)入自己的blog里 
(其實(shí)忘了以前常做下載頁面download.aspx也不過是處理了httphandler的虛頁面而已,可能是見在.text興奮的連這些基本常識(shí)都忘了^_^) 
二、居然可以拿用戶名做用戶的唯一標(biāo)識(shí)但在表里面沒有找到做為用戶名username唯一約束的東東(到現(xiàn)在還不清楚在數(shù)據(jù)庫哪個(gè)地方設(shè)置的,有知道的請(qǐng)指點(diǎn)下) 
后來通過重得注冊同一用戶名查看拋出的異常信息,確認(rèn)確實(shí)在有username做為唯一約束的東東。 
唉,看來我對(duì)數(shù)據(jù)庫一無所知。 
...后來決定專寫一篇關(guān)于url重寫的文章,后來看到dottext的原作者也簡單介紹了下urlrewrite,于是這個(gè)想法就放棄了。 
后來又有一些朋友問dottext關(guān)于url的問題,看來還是寫吧 
2、配置文件webconfig.config簡單瀏覽 
自定義配置節(jié)內(nèi)容: 
 <configsections> 
  <section name="blogconfigurationsettings" type="dottext.framework.util.xmlserializersectionhandler, dottext.framework" /> 
  <section name="handlerconfiguration" type="dottext.framework.util.xmlserializersectionhandler, dottext.framework" /> 
  <section name="searchconfiguration" type="dottext.framework.util.xmlserializersectionhandler, dottext.framework" /> 
  <section name="microsoft.web.services" type="microsoft.web.services.configuration.webservicesconfiguration, microsoft.web.services, version=2.0.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" /> 
  <section name="codehighlighter" type="actiprosoftware.codehighlighter.codehighlighterconfigurationsectionhandler, actiprosoftware.codehighlighter" /> 
 </configsections> 
httphandler的配置內(nèi)容: 
 <httphandlers> 
  <add verb="*" path="*.asmx" type="system.web.services.protocols.webservicehandlerfactory, system.web.services, version=1.0.5000.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a" 
   validate="false" /> 
  <add verb="*" path="error.aspx" type="system.web.ui.pagehandlerfactory" /> 
  <add verb="*" path="*" type="dottext.common.urlmanager.urlrewritehandlerfactory,dottext.common" /> 
 </httphandlers> 
httpmodule的配置內(nèi)容: 
 <httpmodules> 
  <add name="urlrewritemodule" type="dottext.common.urlmanager.urlrewritemodule, dottext.common" /> 
  <add name="eventhttpmodule" type="dottext.framework.scheduledevents.eventhttpmodule, dottext.framework" /> 
 </httpmodules> 
見到一個(gè)陌生的項(xiàng)目首先打開它的配置文件看看,這是我的習(xí)慣:) 
先看看一些重點(diǎn)的配置內(nèi)容: 
看完web.config中的上述內(nèi)容熟悉asp.net運(yùn)行機(jī)制的朋友就明白,dottext代碼的運(yùn)行順序。在這里我再簡單重復(fù)下 
aspnet的內(nèi)部運(yùn)行機(jī)制(若有不熟悉的朋友請(qǐng)參閱<<asp.net famework深度歷險(xiǎn)>>這本書,它對(duì)做asp.net開發(fā)的朋友很有幫助): 
remote client request---->iis---->aspnet_isapi.dll-->aspnet_wp.exe-->httpruntime---> 
httpmodule--->httphandler factory--->httphandler--->httphandler.processrequest()-->response client request 
好了,題歸正轉(zhuǎn),client request首先是被httpmodule截獲。當(dāng)我們請(qǐng)求.text的url:http://www.cnblogs.com/floerggyy/時(shí),首先是 
dottext.common.urlmanager命名空間下類urlrewritemodule的相關(guān)方法被調(diào)用。 
(為什么會(huì)被類urlrewritemodule截獲遠(yuǎn)程請(qǐng)求呢?上面httpmodule配置節(jié)的內(nèi)容不是標(biāo)明了嗎???^_^ 
明知故問,那么為dottext.framework.scheduledevents命名空間下的類eventhttpmodule會(huì)不會(huì)截獲遠(yuǎn)程請(qǐng)求?什么時(shí)候截獲呢? 
當(dāng)然是按先來后順序了,中國的優(yōu)良傳統(tǒng)都忘了!!! 
(其實(shí)這樣說也是不太準(zhǔn)確的,這兩個(gè)httpmodule確是按順序執(zhí)行的但在httpmodule里的一些事件中它們是交叉運(yùn)行的,好了類eventhttpmodule 
不在我們的計(jì)論范圍內(nèi)在下面的代碼就不分析了,有對(duì)這塊不明白的最好去看下上面推薦的那本書^_^) 
3 、url重寫,部分代碼分析(這塊涉及到眾多自定義配置節(jié)、httpmodule、httphandler的綜合應(yīng)用所以要理順還是有點(diǎn)麻煩的,要有一小點(diǎn)分析別人代碼的耐心。個(gè)人認(rèn)為) 
類urlrewritemodule的方法 
private void context_beginrequest(object sender, eventargs e){ 
//它是主要作用是根據(jù)請(qǐng)求匹配正則表達(dá)式來設(shè)置是否重寫客戶所請(qǐng)求的url(它默認(rèn)是重寫url),注意這句代碼urlhelper.setenableurlrewriting(context,false); 
 if(configprovider.instance().isaggregatesite){ 
    httpcontext context  = ((httpapplication)sender).context; 
    string path = context.request.path.tolower(); 
    int iextrastuff = path.indexof(".aspx"); 
    if(iextrastuff > -1 || path.indexof(".") == -1) { 
     if(iextrastuff > -1) 
     { 
      path = path.remove(iextrastuff+5,path.length - (iextrastuff+5)); 
     } 
     path = regexapplication.replace(path,string.empty,1,0); 
     if(path == "" || path == "/"  || regexpath.ismatch(path)) 
     { 
      urlhelper.setenableurlrewriting(context,false); 
     } 
      
    }else if(context.request.path.tolower().indexof("services") > 0 && context.request.path.tolower().indexof(".asmx") > 0 ) 
    { 
     if(alllowservice(context)) 
     { 
      if(context.request.requesttype!="post") 
      { 
       string [email protected]"http://w+/services/"; 
       string url=regex.replace(context.request.rawurl,regexstr,"/services/",regexoptions.ignorecase); 
       context.rewritepath(url); 
      } 
      //string filename =context.request; //system.io.path.getfilename(context.request.path); 
      //context.rewritepath("~/services/" + filename); 
     }else{ 
      context.response.clear(); 
      context.response.end(); 
     } 
    } 
    
   } 
httpmodule處理完后(這句話并不正確,在這里是這樣的)進(jìn)入httphandler factory,根據(jù)httphandler的配置內(nèi)容我們可以馬上找到這個(gè)類 
urlrewritehandlerfactory它是處理重寫url請(qǐng)求核心,在這里我詳細(xì)分析下。 
它實(shí)現(xiàn)了ihttphandlerfactory 
(看注釋就知道這個(gè)類是很重要的了) 
httpmodule處理完后(這句話并不正確,在這里是這樣的)進(jìn)入httphandler factory,根據(jù)httphandler的配置內(nèi)容我們可以馬上找到這個(gè)類 
urlrewritehandlerfactory它是處理重寫url請(qǐng)求核心,在這里我詳細(xì)分析下。 
它實(shí)現(xiàn)了ihttphandlerfactory 
(看注釋就知道這個(gè)類是很重要的了) 
using system; 
using system.web; 
using system.web.ui; 
using system.text.regularexpressions; 
using dottext.framework; 
using dottext.framework.components; 
using dottext.framework.configuration; 
namespace dottext.common.urlmanager 
{ 
    /**//// <summary> 
    /// class responisble for figuring out which .text page to load. by default will load an array of dottext.urlmanager.httphanlder 
    /// from the blog.config file. this contains a list of regex patterns to match the current request to. it also allows caching of the  
    /// regex’s and types 
    /// </summary> 
    public class urlrewritehandlerfactory:  ihttphandlerfactory 
    { 
        public urlrewritehandlerfactory(){} //nothing to do in the cnstr 
        //自定義虛方法從自定義配置節(jié)內(nèi)容反序列化時(shí)構(gòu)造httphandler 
        protected virtual httphandler[] gethttphandlers(httpcontext context) 
        { 
            return handlerconfiguration.instance().httphandlers; 
        } 
        /**//// <summary> 
        /// implementation of ihttphandlerfactory. by default, it will load an array of httphanlder (dottext.urlmanager.httphandler) from 
        /// the blog.config. this can be changed, by overrideing the gethttphandlers(httpcontext context) method.  
        /// </summary> 
        /// <param name="context">current httpcontext</param> 
        /// <param name="requesttype">request type (passed along to other ihttphandlerfactory’s)</param> 
        /// <param name="url">the current requested url. (passed along to other ihttphandlerfactory’s)</param> 
        /// <param name="path">the physical path of the current request. is not gaurenteed to exist (passed along to other ihttphandlerfactory’s)</param> 
        /// <returns> 
        /// returns an instance of ihttphandler either by loading an instance of ihttphandler or by returning an other 
        /// ihttphandlerfactory.gethanlder(httpcontext context, string requesttype, string url, string path) method 
        /// </returns> 
         //實(shí)現(xiàn)接口ihttphandlerfactory定義的方法 
        public virtual ihttphandler gethandler(httpcontext context, string requesttype, string url, string path) 
        { 
            //get the handlers to process. by defualt, we grab them from the blog.config 
            httphandler[] items = gethttphandlers(context); 
            //dottext.framework.logger.logmanager.log("path",dottext.framework.util.globals.removeappfrompath(context.request.path,context.request.applicationpath)); 
            //do we have any? 
            if(items != null) 
            { 
                int count = items.length; 
                for(int i = 0; i<count; i++) 
                { 
                    //we should use our own cached regex. this should limit the number of regex’s created 
                    //and allows us to take advantage of regexoptons.compiled  
                    //逐個(gè)匹配所配置節(jié)中定義的請(qǐng)求類型 
                    if(items[i].ismatch(dottext.framework.util.globals.removeappfrompath(context.request.path,context.request.applicationpath))) 
                    { 
                       //注意這里是關(guān)鍵,注意返回的httphandler實(shí)例 
                            //throw new exception(); 
                        switch(items[i].handlertype) 
                        { 
                            case handlertype.page://默認(rèn)是page 
                                                         
                                return proccesshandlertypepage(items[i],context,requesttype,url); 
                            case handlertype.direct: 
                                handlerconfiguration.setcontrols(context,items[i].blogcontrols); 
                                return (ihttphandler)items[i].instance(); 
                            case handlertype.factory: 
                                //pass a long the request to a custom ihttphandlerfactory 
                                return ((ihttphandlerfactory)items[i].instance()).gethandler(context,requesttype,url,path); 
                            default: 
                                throw new exception("invalid handlertype: unknown"); 
                        } 
                    } 
                } 
            } 
            //if we do not find the page, just let asp.net take over 
            return pagehandlerfactory.gethandler(context,requesttype,url, path); 
        } 
        private ihttphandler proccesshandlertypepage(httphandler item, httpcontext context, string requesttype, string url) 
        { 
            string pagepath = item.fullpagelocation; 
            if(pagepath == null) 
            { 
                pagepath = handlerconfiguration.instance().fullpagelocation; 
            } 
            handlerconfiguration.setcontrols(context,item.blogcontrols); 
            ihttphandler myhandler=pageparser.getcompiledpageinstance(url,pagepath,context); 
            return myhandler; 
        } 
        public virtual void releasehandler(ihttphandler handler)  
        { 
        } 
    } 
} 
要注意它是如何把自定義配置節(jié)中的內(nèi)容拈合成httphandler的實(shí)例 
把這些理順后對(duì)于理解.text的url重寫就不難了.... 
對(duì)上面若有理解不正解的歡迎高手指正