2008-12-09 92 views
10

我在IIS7上運行的ASP.NET 3.5應用程序中使用Context.RewritePath()。IIS7,RewritePath和IIS日誌文件

我在應用程序BeginRequest事件和一切工作文件中這樣做。

將/ sports的請求正確地重寫爲default.aspx?id = 1,依此類推。

問題是,在我的IIS日誌中,我看到/Default.aspx?id=1的GET請求,而不是/ sports。

這種代碼在IIS6下完美工作。

由於必須實施某些業務邏輯,因此不能使用Microsoft Rewrite模塊。

謝謝。

編輯:

看來我的處理程序是在管線爲時尚早,但如果我移動邏輯到以後的事件,比整個重寫的東西不起作用(爲時已晚,StaticFileHandler拿起我的請求)。

我用Google搜索了一下,問了一下,不敢相信沒有人有這個問題?

編輯:

哎呀!這是我在IIS論壇上找到的:

「這是因爲在集成模式下,IIS和asp.net共享一個通用管道,並且IIS現在可以看到RewritePath,而在IIS6中,IIS甚至沒有看到 - 你可以通過使用經典的模式來解決這個問題,它的行爲就像IIS6一樣。「

最終更新:請看看my answer below,我已經在生產環境中使用了一年多的結果更新了它。

+0

Muerte,這樣做的正確方法是回答你自己的問題。您指出,通過將IIS 7置入經典模式(與IIS 6執行相同的操作方式),可以解決此問題。只要您意識到您不會從新IIS 7中的安全性或性能升級中受益,那麼這似乎是一個合理的答案。 – Spence 2009-02-17 12:47:29

+0

我明白我可以回答我自己的問題,但我不認爲這是一個答案,我仍然在追求這個追求。 :)我嘗試了一些東西,並且我一定會添加我的結果,無論是作爲答案還是作爲我的問題的最終編輯。 – muerte 2009-02-17 15:50:19

+0

我會(並且只是)通過Reflector來查看System.Web.Routing程序集。看哪裏掛鉤。 IIRC,你需要在PostMapRequestHandler和PostAcquireRequestState中完成。 – leppie 2009-02-12 11:50:32

回答

6

經過一番研究,我終於找到了解決問題的辦法。

我已經使用新的(在ASP.NET 3.5中引入的)Context.Server.TransferRequest()方法替換了對Context.RewritePath()方法的調用。

現在看起來很明顯,但並不是IIS core團隊的高級開發工程師認爲這一點。

我測試過它的會話,身份驗證,回發,querystring,...問題,沒有發現。

Tommorow我會將這個改變部署到一個非常高的流量站點,我們很快就會知道它是如何工作的。 :)

我會回來的更新。

更新:該解決方案仍然不是完全在我的生產服務器上,但它已經過測試,它的確工作,並且據我所知,這是我的問題的解決方案。如果我在製作中發現其他任何內容,我會發布更新。

最終更新:我有這個解決方案在生產一年多,它已被證明是一個良好和穩定的解決方案沒有任何問題。

4

在處理完請求之後但在IIS日誌記錄模塊寫入日誌條目之前,您可以將路徑設置回原始值。

例如,此模塊重寫BeginRequest上的路徑,然後將其設置回原始值EndRequest。當使用此模塊時,原始路徑出現在IIS日誌文件中:

public class RewriteModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += OnBeginRequest; 
     context.EndRequest += OnEndRequest; 
    } 

    static void OnBeginRequest(object sender, EventArgs e) 
    { 
     var app = (HttpApplication)sender; 
     app.Context.Items["OriginalPath"] = app.Context.Request.Path; 
     app.Context.RewritePath("Default.aspx?id=1"); 
    } 

    static void OnEndRequest(object sender, EventArgs e) 
    { 
     var app = (HttpApplication)sender; 
     var originalPath = app.Context.Items["OriginalPath"] as string; 
     if (originalPath != null) 
     { 
      app.Context.RewritePath(originalPath); 
     } 
    } 

    public void Dispose() 
    { 

    } 
} 
2

我有完全相同的問題。解決這個問題的一個方法是使用Server.Transfer而不是Context.RewritePath。 Server.Transfer不會重新啓動整個頁面生命週期,因此原始URL仍將被記錄。一定要爲「preserveForm」參數傳遞「true」,以便QueryString和Form集合可用於第二頁。

0

老問題,但我發現我沒有遇到您的問題時,我做了以下內容:

一)在web.config中重寫規則將所有請求/default.aspx,如:

<rule name="all" patternSyntax="Wildcard" stopProcessing="true"> 
     <match url="*"/> 
     <action type="Rewrite" url="/default.aspx"/> 
    </rule> 

b)在default.aspx的Page_PreInit事件中調用RewritePath,將URL和查詢字符串重寫爲請求中傳遞的內容(即不存在的位置)。

例如,我請求「/ somepage /?x = y」(不存在)。

一個)的Web.config規則映射它/default.aspx

b)中Page_PreInit重寫回 「/ SomePage的/?X = Y」。

在IIS 7(Express和Production)中,這樣做的結果是服務器日誌反映了存根的「/ somepage」和查詢的「x = y」,並且所有的Request對象屬性都反映了請求的存在)URL(這是我想要的)。

唯一奇怪的是,在IIS Express中,日誌項被寫入兩次。但是,這在生產(Windows Server 2008 R2)中不會發生。