標籤:部分 rar 自訂 分享 gac format content 許可權 日誌
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伺服器是只能識l檔案的,當IIS伺服器發現被請求的檔案是.aspx檔案時,IIS伺服器將其交給aspnet_isapi.dll來處理。
aspnet_wp.exe進程:ASP.NET架構進程,提啟動並執行託管環境的CLR(通用語言執行平台)就是寄存在此進程中。
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中都可以幹預請求的處理過程。
注意:在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應用程式的輸出緩衝是如何設定的。
上面這麼多的事件,我們看起來可能會有些眼暈,但沒關係,下面一步一步地看。
HttpModule生命週期
下面是事件的觸發順序:
BeginRequest和PreRequestHandlerExecute之間的事件是在伺服器執行HttpHandler處理之前觸發。
PostRequestHandlerExecute和PreSendRequestContent之間的事件是在伺服器執行Handler處理之後觸發。
下面我們看一下如何使用HttpModule來實現我們日常的應用:
HttpModule通過在某些事件中註冊,把自己插入ASP.NET請求處理管道。當這些事件發生的時候,ASP.NET調用對相應的HTTP模組,這樣該模組就能處理請求了。
1、向每個頁面動態添加一些備忘或說明性的文字:
有的網站每一個頁面都會彈出一個廣告或在每個頁面都以注釋形式(<!-- -->)加入網站的著作權資訊。如果在每個頁面教編寫這樣的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代碼。
2、身份檢查
大家在作登入時,登入成功後,一般要把使用者名稱放在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>
3、多模組的操作
如果定義了多個HttpModule,在nfig檔案中引入自訂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。
根據這個例子大家可以考慮一下如何編寫“驗證碼”了。
IHttpHandler工廠
IHttpHandlerFactory的作用是對IHttpHandler進行管理。工廠的作用請見ml"
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則屬於挑食類型,只有註冊過的檔案類型(例如aspx,asmx等等)才會輪到調用它.
3.IHttpHandler按照你的請求 產生響應的內容,IHttpModule對請求進行預先處理,如驗證、修改、過濾等等,同時也可以對響應進行處理
ASP.Net系統本身配置有很多HttpHandler和HttpModule,以處理aspx等.Net標準的分頁檔,以及這些分頁檔中標 準的事件處理等。查看%System%/Microsoft.NET\Framework\v2.0.50727\CONFIG目錄下的 nfig檔案中的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項目的nfig檔案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>
注意要區分大小寫,因為nfig作為一個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配置一個為尾碼名的檔案類型,用我們寫的MyHttpHandler來處理。
首先,在IIS網站的Configuration配置裡面,添加一個尾碼名處理的Application Extention Mapping項。
然後,在web項目的nfig節點節點中配置:
MyHttpHandler, MyHandler"/>
verb屬性配置這個HttpHandler處理那些HTTP方法,例如GET、POST等,如果是處理所有方法,就用*。path屬性配置HttpHandler對哪些檔案進行處理,例如可以是,如果是處理所有檔案,就用。
這樣,這個網站上所類型檔案的訪問,都由MyHttpHandler處理。使//localhost/網站虛擬目錄/訪問測試網站,可以看到測試效果。當然,這個檔案在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重寫的
我們經常看到很多網站訪問文章的時候才用的是**l 或***.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+");
//用Regex進行匹配
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項目中若要使用此功能,需要在nfig裡面加上如下語句:
<httpHandlers>
<add verb="*" path="*.shtml" type="HttpHandle.UrlRewrite" />
</httpHandlers>
同時,還要在IIS中對Web項目進行配置,在Web項目的屬性中,在主目錄選項卡裡,把執行許可權改為"指令碼和可執行檔",然後開啟配置,在應用程式擴充裡加上需重寫的檔案格式的擴充,好了,成事具備,只欠運行了。
httpModules與httpHandlers