httpModules 與 httpHandlers【轉載】

ASP.NET對請求處理的過程:
當請求一 個*.aspx文件的時候,這個請求會被inetinfo.exe進程截獲,它判斷文件的後綴(aspx)以後,將這個請求轉交給 ASPNET_ISAPI.dll,ASPNET_ISAPI.dll會經過http管道(Http PipeLine)將請求發送給ASPNET_WP.exe進程,在ASPNET_WP.exe進程中經過HttpRuntime來處理這個請求,處理完 畢將結果返回客戶端。
    inetinfo.exe進程:是www服務的進程,IIS服務和ASPNET_ISAPI.DLL都寄存在此進程中。
    ASPNET_ISAPI.DLL:是處理.aspx文件的win32組件。其實IIS服務器是隻能識別.html文件的,當IIS服務器發現被請求的文件是.aspx文件時,IIS服務器將其交給aspnet_isapi.dll來處理。
    aspnet_wp.exe進程:ASP.NET框架進程,提供.net運行的託管環境,.net的CLR(公共語言運行時)就是寄存在此進程中。html

ASP.NET Framework處理一個Http Request的流程:
    HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

ASP.NET 請求處理過程是基於管道模型的,這個管道模型是由多個HttpModule和HttpHandler組成,ASP.NET把http請求依次傳遞給管道中 各個HttpModule,最終被HttpHandler處理,處理完成後,再次通過管道中的HTTP模塊,把結果返回給客戶端。咱們能夠在每一個 HttpModule中均可以干預請求的處理過程。web

 

 

注意:在http請求的處理過程當中,只能調用一個HttpHandler,但能夠調用多個HttpModule。
當 請求到達HttpModule的時候,系統尚未對這個請求真正處理,可是咱們能夠在這個請求傳遞處處理中心(HttpHandler)以前附加一些其它 信息,或者截獲的這個請求並做一些額外的工做,也或者終止請求等。在HttpHandler處理完請求以後,咱們能夠再在相應的HttpModule中把 請求處理的結果進行再次加工返回客戶端。正則表達式

HttpModule
    HTTP模塊是實現了System.Web.IhttpModule接口的類。
    IHttpModule接口的聲明:
        public interface IHttpModule
        {
            void Init (HttpApplication context);
            void Dispose ();
        }
        Init 方法:系統初始化的時候自動調用,這個方法容許HTTP模塊向HttpApplication 對象中的事件註冊本身的事件處理程序。
        Dispose方法: 這個方法給予HTTP模塊在對象被垃圾收集以前執行清理的機會。此方法通常無需編寫代碼。
   
    HTTP模塊能夠向System.Web.HttpApplication對象註冊下面一系列事件:
        AcquireRequestState 當ASP.NET運行時準備好接收當前HTTP請求的對話狀態的時候引起這個事件。
        AuthenticateRequest 當ASP.NET 運行時準備驗證用戶身份的時候引起這個事件。
        AuthorizeRequest 當ASP.NET運行時準備受權用戶訪問資源的時候引起這個事件。
        BeginRequest 當ASP.NET運行時接收到新的HTTP請求的時候引起這個事件。
        Disposed 當ASP.NET完成HTTP請求的處理過程時引起這個事件。
        EndRequest 把響應內容發送到客戶端以前引起這個事件。
        Error 在處理HTTP請求的過程當中出現未處理異常的時候引起這個事件。
        PostRequestHandlerExecute 在HTTP處理程序結束執行的時候引起這個事件。
        PreRequestHandlerExecute 在ASP.NET開始執行HTTP請求的處理程序以前引起這個事件。在這個事件以後,ASP.NET 把該請求轉發給適當的HTTP處理程序。
        PreSendRequestContent 在ASP.NET把響應內容發送到客戶端以前引起這個事件。這個事件容許咱們在內容到達客戶端以前改變響應內容。咱們可使用這個事件給頁面輸出添加用於全部頁面的內容。例如通用菜單、頭信息或腳信息。
        PreSendRequestHeaders 在ASP.NET把HTTP響應頭信息發送給客戶端以前引起這個事件。在頭信息到達客戶端以前,這個事件容許咱們改變它的內容。咱們可使用這個事件在頭信息中添加cookie和自定義數據。
        ReleaseRequestState 當ASP.NET結束所搜有的請求處理程序執行的時候引起這個事件。
        ResolveRequestCache 咱們引起這個事件來決定是否可使用從輸出緩衝返回的內容來結束請求。這依賴於Web應用程序的輸出緩衝時怎樣設置的。
        UpdateRequestCache 當ASP.NET完成了當前的HTTP請求的處理,而且輸出內容已經準備好添加給輸出緩衝的時候,引起這個事件。這依賴於Web應用程序的輸出緩衝是如何設置的。api

    上面這麼多的事件,咱們看起來可能會有些眼暈,但不要緊,下面一步一步地看。
    HttpModule生命週期示意圖緩存

 

下面是事件的觸發順序:服務器

 

BeginRequest和PreRequestHandlerExecute之間的事件是在服務器執行HttpHandler處理以前觸發。
    PostRequestHandlerExecute和PreSendRequestContent之間的事件是在服務器執行Handler處理以後觸發。cookie

 

 

 

 下面咱們看一下如何使用HttpModule來實現咱們平常的應用:
        HttpModule經過在某些事件中註冊,把本身插入ASP.NET請求處理管道。當這些事件發生的時候,ASP.NET調用對相應的HTTP模塊,這樣該模塊就能處理請求了。
       一、向每一個頁面動態添加一些備註或說明性的文字:
            有的網站每個頁面都會彈出一個廣告或在每一個頁面都以註釋形式(<!-- -->)加入網站的版權信息。若是在每一個頁面教編寫這樣的JS代碼的話,對於大一點的網站,這種JS代碼的編寫與維護但是一個很繁瑣枯燥的工做。
            有了HttpModule咱們就能夠很簡單地解決這個問題了。HttpModule是客戶端發出請求到客戶端接收到服務器響應之間的一段必經之路。咱們完 全能夠在服務器處理完請求以後,並在向客戶端發送響應文本以前這段時機,把這段註釋文字添加到頁面文本以後。這樣,每個頁面請求都會被附加上這段註釋文 字。
            這段代碼究竟該在哪一個事件裏實現呢? PostRequestHandlerExecute和PreSendRequestContent之間的任何一個事件均可以,但我比較喜歡在EndRequest事件裏編寫代碼。
            第一步:建立一個類庫ClassLibrary831。
            第二步:編寫一個類實現IHttpModule接口
               class TestModule:IHttpModule
                {
                    public void Dispose()
                    {
                    }
                    public void Init(HttpApplication context)
                    {
                    }
                }
            第三步:在Init事件中註冊EndRequest事件,並實現事件處理方法
               class TestModule:IHttpModule
                {
                    public void Dispose(){}
                    public void Init(HttpApplication context)
                    {
                        context.EndRequest += new EventHandler(context_EndRequest);
                    }
                    void context_EndRequest(object sender, EventArgs e)
                    {
                        HttpApplication ha = (HttpApplication)sender;
                        ha.Response.Write("<!--這是每一個頁面都會動態生成的文字。--grayworm-->");
                    }
                }
            第四步:在Web.Conofig中註冊一下這個HttpModule模塊
          
<httpModules>
           <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
          </httpModules>
          name:模塊名稱,通常是類名
          type:有兩部分組成,前半部分是命名空間和類名組成的全名,後半部分是程序集名稱,若是類是直接放在App_Code文件夾中,那程序名稱是App_Code。
                這樣在Web站點是添加該類庫的引用後,運行每一個頁面,會發現其源文件中都會加入「<!--這是每一個頁面都會動態生成的文字。--grayworm-->」這句話。一樣的方法你也能夠在其中加入JS代碼。
       二、身份檢查
            你們在做登陸時,登陸成功後,通常要把用戶名放在Session中保存,在其它每個頁面的Page_Load事件中都檢查Session中是否存在用戶名,若是不存在就說明用戶未登陸,就不讓其訪問其中的內容。
            在比較大的程序中,這種作法實在是太笨拙,由於你幾乎要在每個頁面中都加入檢測Session的代碼,致使難以開發和維護。下面咱們看看如何使用HttpModule來減小咱們的工做量
            因爲在這裏咱們要用到Session中的內容,咱們只能在AcquireRequestState和PreRequestHandlerExecute事 件中編寫代碼,由於在HttpModule中只有這兩事件中能夠訪問Session。這裏咱們選擇PreRequestHandlerExecute事件 編寫代碼。
            第一步:建立一個類庫ClassLibrary831。
            第二步:編寫一個類實現IHttpModule接口
                class TestModule:IHttpModule
                {
                    public void Dispose()
                    {
                    }
                    public void Init(HttpApplication context)
                    {
                    }
                }
            第三步:在Init事件中註冊PreRequestHandlerExecute事件,並實現事件處理方法
               class AuthenticModule:IHttpModule
                {
                    public void Dispose(){}
                    public void Init(HttpApplication context)
                    {
                        context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
                    }
                    void context_PreRequestHandlerExecute(object sender, EventArgs e)
                    {
                        HttpApplication ha = (HttpApplication)sender;
                        string path = ha.Context.Request.Url.ToString();
                        int n = path.ToLower().IndexOf("Login.aspx");
                        if (n == -1) //是不是登陸頁面,不是登陸頁面的話則進入{}
                        {
                            if (ha.Context.Session["user"] == null) //是否Session中有用戶名,如果空的話,轉向登陸頁。
                            {
                                ha.Context.Response.Redirect("Login.aspx?source=" + path);
                            }
                        }
                    }
                }
            第四步:在Login.aspx頁面的「登陸」按鈕中加入下面代碼
                protected void Button1_Click(object sender, EventArgs e)
                {
                    if(true)    //判斷用戶名密碼是否正確
                    {
                        if (Request.QueryString["source"] != null)
                        {
                            string s = Request.QueryString["source"].ToLower().ToString();   //取出從哪一個頁面轉來的
                            Session["user"] = txtUID.Text;
                            Response.Redirect(s); //轉到用戶想去的頁面
                        }
                        else
                        {
                            Response.Redirect("main.aspx");    //默認轉向main.aspx
                        }
                    }
                }
            第五步:在Web.Conofig中註冊一下這個HttpModule模塊
          
<httpModules>
           <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
          </httpModules>
       三、多模塊的操做
            若是定義了多個HttpModule,在web.config文件中引入自定義HttpModule的順序就決定了多個自定義HttpModule在處理一個HTTP請求的接管順序。
架構

HttpHandler
    HttpHandler是HTTP請求的處理中心,真正地對客戶端請求的服務器頁面作出編譯和執行,並將處理事後的信息附加在HTTP請求信息流中再次返回到HttpModule中。
    HttpHandler與HttpModule不一樣,一旦定義了本身的HttpHandler類,那麼它對系統的HttpHandler的關係將是「覆蓋」關係。
    IHttpHandler接口聲明
    public interface IHttpHandler
    {
        bool IsReusable { get; }
        public void ProcessRequest(HttpContext context); //請求處理函數
    }
   
    示例:把硬盤上的圖片以流的方式寫在頁面上
        class TestHandler : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);
                byte[] b = new byte[fs.Length];
                fs.Read(b, 0, (int)fs.Length);
                fs.Close();
                context.Response.OutputStream.Write(b, 0, b.Length);
            }
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
        }
        Web.Config配置文件
      <httpHandlers>
       <add verb="*" path="*" type="ClassLibrary831.TestHandler,ClassLibrary831"></add>
      </httpHandlers>
           Verb屬性:指定了處理程序支持的HTTP動做。*-支持全部的HTTP動做;「GET」-支持Get操做;「POST」-支持Post操做;「GET, POST」-支持兩種操做。
  Path屬性:指定了須要調用處理程序的路徑和文件名(能夠包含通配符)。「*」、「*.aspx」、「showImage.aspx」、「test1.aspx,test2.aspx」
  Type屬性:用名字空間、類名稱和程序集名稱的組合形式指定處理程序或處理程序工廠的實際類型。ASP.NET運行時首先搜索bin目錄中的DLL,接着在GAC中搜索。
        這樣程序運行的效果是該網站的任何一個頁面都會顯示worm.jpg圖片。如何只讓一個頁面(default21.aspx)執行HttpHandler 中的ProcessRequest方法呢?最簡單的辦法是在Web.Config文件中把path配置信息設爲default21.aspx。
        根據這個例子你們能夠考慮一下如何編寫「驗證碼」了。app

IHttpHandler工廠
    IHttpHandlerFactory的做用是對IHttpHandler進行管理。工廠的做用請見http://hi.baidu.com/grayworm/blog/item/4a832160f8c9de46eaf8f8c1.html"
    IHttpHandlerFactory接口的聲明:
        public interface IHttpHandlerFactory
        {
            IHttpHandler GetHandler (HttpContext context,string requestType,string url,string pathTranslated);
            void ReleaseHandler (IHttpHandler handler);
        }
       GetHandler返回實現IHttpHandler接口的類的實例,ReleaseHandler使工廠能夠重用現有的處理程序實例。
    示例:兩個用IHttpHandlerFactory來實現對不一樣HttpHandler的調用。
    有兩個HttpHandler:將圖片顯示在頁面上的HttpHandler和生成驗證碼的Handler
        //將圖片顯示在頁面上的Handler
        class TestHandler : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);
                byte[] b = new byte[fs.Length];
                fs.Read(b, 0, (int)fs.Length);
                fs.Close();
                context.Response.OutputStream.Write(b, 0, b.Length);
            }
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
        }
        //生成驗證碼的Handler
        class CodeHandler:IHttpHandler
        {
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
            public void ProcessRequest(HttpContext context)
            {
                Image b = new Bitmap(50,20);
                Graphics g = Graphics.FromImage(b);
                SolidBrush sb = new SolidBrush(Color.White);
                Font f = new Font("宋體", 12);
                string str = "";
                Random r = new Random();
                for (int i = 0; i < 4; i++)
                {
                    str += r.Next(10);
                }
                g.DrawString(str,f,sb,0,0);
                b.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
        }
         IHttpHandler工廠
         class TestHandlerFactory : IHttpHandlerFactory
         {
            public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
            {
               
                string fname = url.Substring(url.IndexOf('/') + 1);
                while (fname.IndexOf('/') != -1)
                    fname = fname.Substring(fname.IndexOf('/') + 1);
                string cname = fname.Substring(0, fname.IndexOf('.'));
                string className ="";
框架

                className = "ClassLibrary831.CodeHandler";
                object h = null;
                try
                {
                    //h = new TestHandler();
                    h = Activator.CreateInstance(Type.GetType(className));
                }
                catch (Exception e)
                {
                    throw new HttpException("工廠不能爲類型" + cname + "建立實例。", e);
                }
                return (IHttpHandler)h;
            }
            public void ReleaseHandler(IHttpHandler handler)
            {
            }
         }(車延祿)
        配置文件
    <httpHandlers>
    <add verb="*" path="default21.aspx,default22.aspx" type="ClassLibrary831.TestHandlerFactory,ClassLibrary831"></add>
   </httpHandlers>

   這樣TestHandlerFactory就會根據請求的不一樣頁面執行不一樣的HttpHandler處理程序了。

HttpHandler使用會話
    若是要在處理程序中使用Session,那必須把該HttpHandler實現IRequiresSessionState接口,,IRequiresSessionState接口是個空接口,它沒有抽象方法,只是一個標記。此處就不做例子驗證了

 

 

 

 

ASP.Net處理Http Request時,使用Pipeline(管道)方式,由各個HttpModule對請求進行處理,而後到達 HttpHandler,HttpHandler處理完以後,仍通過Pipeline中各個HttpModule的處理,最後將HTML發送到客戶端瀏覽 器中。

生命週期中涉及到幾個很是重要的對象:HttpHandler,HttpModule,IHttpHandlerFactory,他們的執行(順 序)大體的執行過程是這樣的:client端發送頁面請求,被IIS的某個進程截獲,它根據申請的頁 面後綴(.aspx)不一樣,調用不一樣的頁面處理程序(.asp->asp.dll; .aspx->ISAPI.dll).而頁面處理程序在處理過程當中,則要經歷HttpModule,HttpHandler的處理:前者HttpModule用於頁面處理前和處理後的一些事件的處理後者HttpHandler進行真正的頁面的處理
如 前所說,HttpModule會在頁面處理前和後對頁面進行處理,因此它不會影響真正的頁面請求。一般用在給每一個頁面的頭部或者尾部添加一些信息(如版 權聲明)等.曾經見過一些免費的空間,咱們的頁面上傳上去後,瀏覽的時候發現,在每一個頁面的頭部和尾部多了不少小廣告....,若是理解了 HttpModule的原理,要作這個就不是很難了~


IHttpModule與IHttpHandler的區別整理
    1.前後次序.先IHttpModule,後IHttpHandler. 注:Module要看你響應了哪一個事件,一些事件是在Handler以前運行的,一些是在Handler以後運行的
    2.對請求的處理上:
        IHttpModule是屬於大小通吃類型,不管客戶端請求的是什麼文件,都會調用到它;例如aspx,rar,html的請求.
        IHttpHandler則屬於挑食類型,只有ASP.net註冊過的文件類型(例如aspx,asmx等等)纔會輪到調用它.
   3.IHttpHandler按照你的請求 生成響應的內容,IHttpModule對請求進行預處理,如驗證、修改、過濾等等,同時也能夠對響應進行處理

 

 

ASP.Net系統自己配置有不少HttpHandler和HttpModule,以處理aspx等.Net標準的頁面文件,以及這些頁面文件中標 準的事件處理等。查看%System%/Microsoft.NET\Framework\v2.0.50727\CONFIG目錄下的 web.config文件中的httpHandlers和httpModules節點,能夠看到這些配置。若是有興趣,可使用Reflector查 看.Net系統中相關的類和方法,瞭解.Net如何處理以及作了什麼處理。

.Net也提供了一套機制來開發自定義的HttpHandler和 HttpModule,都可以用於對HttpRequest的截取,完成自定義的處理。 HttpModule 繼承System.Web.IHttpModule接口,實現本身的HttpModule類。必需要實現接口的兩個方法:Init和Dispose。在 Init中,能夠添加須要截取的事件;Dispose用於資源的釋放,若是在Init中建立了本身的資源對象,請在Dispose中進行釋放。

namespace MyModule
{
public class MyHttpModule : IHttpModule
{
    public MyHttpModule()
    {
    }

   
   //Init方法用來註冊HttpApplication 事件。
   public void Init(HttpApplication r_objApplication)
    {
      r_objApplication.BeginRequest += new EventHandler(this.BeginRequest);
    }    

 

public void Dispose()
    {
    }    

private void BeginRequest(object r_objSender, EventArgs r_objEventArgs)
    {
      HttpApplication objApp = (HttpApplication)r_objSender;
      objApp.Response.Write("您請求的URL爲" + objApp.Request.Path);
    }
}


}   

將編譯的dll文件拷貝到web項目的bin目錄下,在web項目的web.config文件system.web節點中配置:
    這樣就將自定義的HttpModule類MyHttpModule插入到了當前web的HttpModule的Pipeline中。 HttpModule主要功能是Application的各個事件進行截取,在這些事件中完成本身的處理。其實若是本身開發一些項目,直接在 Global.asax中 處理已經足夠了。若是是開發一個Framework或者是某些方面的組件,須要在事件中添加處理,開發自定義的 HttpModule,能夠避免使用Framework或者組件時,還得手工在Global.asax中添加代碼。     目前想到的開發自定義HttpModule的用途,有全局的身份/權限驗證、自定義網站訪問/操做日誌的記錄、處於管理/調試等目的對站點進行監控追蹤 等。固然,若是是結合自定義的HttpHandler進行Framework的開發,HttpModule能夠用於其它的一些特殊的處理。

      <httpModules>
         <add name="test" type="MyHttpModuleTest.MyHttpModule,MyHttpModule"/>
       </httpModules>
   注意要區分大小寫,由於web.config做爲一個XML文件是大小寫敏感的。「type=MyHttpModuleTest.MyHttpModule,MyHttpModule」告訴咱們
   系統將會將http request請求交給位於MyHttpModule.dll文件中的MyHttpModuleTest.MyHttpModule類去處理。

 

 

 

HttpHandler是徹底的對Http Request的截取。
    首先,繼承System.Web.IHttpHandler接口,實現本身的HttpHandler類。必需要實現接口的ProcessRequest方 法和IsReusable屬性。ProcessRequest方法中完成對每一個Http Request的處理,發送處理結果的HTML到輸出緩存中。IsReusable屬性被.Net Framework調用,用以肯定這個HttpHandler的實例是否能夠被重用於同類型其它的Request處理。
    若是你在本身的HttpHandler類中,須要讀取或者是寫Session值,須要再繼承一個接口IRequiresSessionState。這個接 口沒有任何方法,只是一個標記接口。繼承這個接口以後,就能夠在本身的HttpHandler中訪問Session,能夠在Session中寫入值。
namespace MyHandler
{
public class MyHttpHandler : IHttpHandler, IRequiresSessionState
{
    public MyHttpHandler() {}
    public bool IsReusable
    {
      get { return true; }
    }
    public void ProcessRequest(HttpContext context)
    {
      HttpResponse objResponse = context.Response ;
      objResponse.Write("
This request is handled by MyHttpHandler
");
    }
}
}
    把編譯的dll文件拷貝到web項目的bin目錄下。
    接下來,這樣來測試一下MyHttpHandler。咱們爲IIS配置一個以.cc爲後綴名的文件類型,用咱們寫的MyHttpHandler來處理。
    首先,在IIS站點的Configuration配置裏面,添加一個對.cc後綴名處理的Application Extention Mapping項。  
    而後,在web項目的web.config節點節點中配置:

MyHttpHandler, MyHandler"/>

    verb屬性配置這個HttpHandler處理那些HTTP方法,例如GET、POST等,若是是處理全部方法,就用*。path屬性配置HttpHandler對哪些文件進行處理,例如能夠是myfile.cc,若是是處理全部的.cc文件,就用*.cc。
    這樣,這個站點上全部.cc類型文件的訪問,都由MyHttpHandler處理。使用http://localhost/站點虛擬目錄/a.cc訪問測試站點,能夠看到測試效果。固然,a.cc這個文件在Web服務器上是並不存在的。

    對HttpHandler的使用,比較典型的有.Net的Web MVC開源項目Maverick。Maverick使用一個Dispatcher類對全部的Http Request進行截取,他以.m做爲後綴名向Web服務器提交請求,在Dispatcher中,將.m的後綴去掉,提取Command Name,而後以這個command name從配置文件中加載處理的flow,造成一個chain,依次對chain上的各個command和view進行處理,對各個command和 view的處理結果可能會在chain中選擇不一樣的處理分支,每一個處理的Step中將處理結果的HTML寫入Response的緩存中進行輸出。
    整體來講,Maverick的框架架構概念很不錯,但也存在明顯的缺陷,之後有時間再詳細的寫寫它的架構和須要改進之處。

    總之,將HttpModule、HttpHandler,以及使用Ajax等將客戶端進行封裝結合起來,可以給web項目的開發帶來很是大的改善空間。

Asp.Net HttpHandler實現URL重寫的
咱們常常看到不少網站訪問文章的時候才用的是***.html 或***.shtml (如本blog的日誌訪問效果),其時這寫文件在服務器上不存在的,那爲何會出現這樣的效果呢,是由於Web服務器上對URL執行了重寫,把訪問的 URL根據特定的格式重寫成內部訪問頁面來實現的,它的好處是便於用戶理解,同時搜索引擎也能更好地收入你的網站,固然其它的好處也不少,這裏不作一一介 紹了。
本文所講的是使用Asp.Net中的HttpHandler實現URL重寫的,它所實現的原理請看這裏,本程序能夠處理任何Url,由於我在程序中使用了URL過慮,只有訪問文件名是數字的才進行處理,並指在內部執行一個新的頁面,並輸出數據,代碼以下:
public void ProcessRequest(HttpContext Context)
{   
try {       
         //申明Request        
HttpRequest Request = Context.Request;
//取來路Url的絕對路徑       
string Url = Request.Url.AbsolutePath;
//取訪問的Web文件的開始字符間隔數
int RegStart = Url.LastIndexOf("/") + 1;
//申明一個肯定Web文件名是否全是數字
Regex Reg = new Regex(@"\d+");
//用正則表達式進行匹配
if (Reg.IsMatch(Url, RegStart))
{
// 若是web文件名是數字,則斷定是查詢相關文章,執行指定頁面             Context.Server.Execute("~/PermaLink.aspx?id=" + Reg.Match(Url, RegStart).Value);       
}   
}
catch
{
      Context.Response.Redirect(Context.Request.Url.ToString());
}
}
固然你首先要作的是先建一個類,並繼承自IHttpHandler,而後把這段代碼拷入,並編譯。在Web項目中若要使用此功能,須要在web.config裏面加上以下語句:
<httpHandlers>
    <add verb="*" path="*.shtml" type="HttpHandle.UrlRewrite" />
</httpHandlers>
同時,還要在IIS中對Web項目進行配置,在Web項目的屬性中,在主目錄選項卡里,把執行權限改成"腳本和可執行文件",而後打開配置,在應用程序擴展里加上需重寫的文件格式的擴展,好了,成事具有,只欠運行了。

原文地址:http://www.cnblogs.com/chenlulouis/archive/2009/12/18/1626918.html

相關文章
相關標籤/搜索