2008-12-09 6 views
10

Ich verwende Context.RewritePath() in ASP.NET 3.5-Anwendung, die auf IIS7 ausgeführt wird.IIS7, RewritePath und IIS-Protokolldateien

Ich mache es in der Anwendung BeginRequest Ereignis und alles funktioniert Datei.

Anforderungen für/Sport werden korrekt in default.aspx? Id = 1 umgeschrieben, und so weiter.

Das Problem ist, dass in meinem IIS-Protokoll sehe ich GET-Anfragen für /Default.aspx?id=1 und nicht für/Sport.

Diese Art von Code funktionierte perfekt unter IIS6.

Das Verwenden des Microsoft Rewrite-Moduls ist keine Option, da einige Geschäftslogik implementiert werden muss.

Danke.

EDIT:

Es scheint, mein Handler zu früh in der Pipeline ist, aber wenn ich die Logik zu einem späteren Ereignisse bewegen, als die ganze Rewrite Sache nicht funktioniert (es zu spät ist, StaticFileHandler nimmt meine anfordern).

Ich googelte und googelte, fragte herum, kann nicht glauben, dass niemand dieses Problem hat?

BEARBEITEN:

Huch! Hier ist, was ich im IIS-Forum gefunden:

"Dies ist, weil im integrierten Modus, IIS und asp.net eine gemeinsame Pipeline teilen und der RewritePath jetzt von IIS gesehen wird, während in IIS6 wurde es nicht einmal von IIS gesehen - Sie können dies umgehen, indem Sie den klassischen Modus verwenden, der sich wie IIS6 verhält. "

Schluss Update: Bitte einen Blick auf my answer below nehmen, ich habe es nach mehr als ein Jahr in der Produktionsumgebung mit den Ergebnissen aktualisiert.

+0

Muerte, der richtige Weg dies zu tun wäre, um Ihre eigene Frage zu beantworten. Sie haben angegeben, dass dieses Problem korrekt sein kann, indem Sie IIS 7 in den klassischen Modus versetzen, der genauso wie IIS 6 ausgeführt wird. Solange Sie feststellen, dass Sie nicht von den Sicherheits- oder Leistungsupgrades im neuen IIS 7 profitieren Es scheint eine vernünftige Antwort zu sein. – Spence

+0

Ich verstehe, dass ich meine eigene Frage beantworten kann, aber ich betrachte das nicht als eine Antwort und ich bin immer noch auf der Suche. :) Ich probiere einige Dinge aus, und ich werde definitiv mein Ergebnis hinzufügen, entweder als Antwort oder als letzte Bearbeitung meiner Frage. – muerte

+0

Ich würde (und habe) nur die System.Web.Routing-Assembly über Reflector betrachten. Um zu sehen, wo man es anschließen kann. IIRC, müssen Sie es bei PostMapRequestHandler und PostAcquireRequestState tun. – leppie

Antwort

6

Nach einigen Recherchen habe ich endlich eine Lösung für das Problem gefunden.

Ich habe die Aufrufe der Context.RewritePath() -Methode mit der neuen Methode (eingeführt in ASP.NET 3.5) Context.Server.TransferRequest() Methode ersetzt.

Es scheint jetzt offensichtlich, aber nicht Ereignis Senior Dev Engineer auf IIS Core-Team gedacht.

Ich habe es für Session, Authentifizierung, Postback, Querystring, ... Probleme getestet und keine gefunden.

Morgen werde ich die Änderung auf einer sehr hohen Verkehrsseite bereitstellen, und wir werden bald wissen, wie es tatsächlich funktioniert. :)

Ich werde mit dem Update zurück sein.

Das Update: Die Lösung ist immer noch nicht vollständig auf meinen Produktionsservern aber es ist getestet und es funktioniert und soweit ich bis jetzt sagen kann, es ist eine Lösung für mein Problem. Wenn ich etwas anderes in der Produktion entdecke, werde ich ein Update veröffentlichen.

Das letzte Update: Ich habe diese Lösung in der Produktion seit über einem Jahr und es hat sich als eine gute und stabile Lösung ohne Probleme erwiesen.

+1

+1 Heilige raucht, das hat meinen Tag gerettet! –

+0

Warum scheint es so offensichtlich? –

4

Sie können den Pfad auf den ursprünglichen Wert zurücksetzen, nachdem die Anforderung verarbeitet wurde, aber bevor das IIS-Protokollierungsmodul den Protokolleintrag schreibt.

Zum Beispiel schreibt dieses Modul den Pfad auf BeginRequest neu und setzt es dann auf den ursprünglichen Wert auf EndRequest zurück. Wenn dieses Modul verwendet wird, wird der ursprüngliche Pfad in der IIS-Protokolldatei angezeigt:

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() 
    { 

    } 
} 
+0

Funktioniert das tatsächlich? – Dscoduc

+0

Ja, ich habe es auf Vista mit IIS 7 getestet und überprüft, dass die Webseite den neu geschriebenen Pfad sah, aber dass der ursprüngliche Pfad in die IIS-Protokolldatei geschrieben wurde.Aber ich habe keine detaillierten Tests gemacht, welche Nebenwirkungen dies haben könnte. –

2

Ich hatte genau das gleiche Problem. Eine Möglichkeit besteht darin, Server.Transfer anstelle von Context.RewritePath zu verwenden. Server.Transfer startet den gesamten Seitenlebenszyklus nicht neu, sodass die ursprüngliche URL weiterhin protokolliert wird. Übergeben Sie "true" für den Parameter "preserveForm", damit die QueryString- und Form-Auflistungen für die zweite Seite verfügbar sind.

0

alte Frage, aber ich fand ich habe Ihr Problem nicht auf, wenn ich das folgende tat:

a) Eine Rewrite-Regel in web.config alle Anfragen direkt an /Default.aspx, zB:

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

b) Aufruf von RewritePath im Page_PreInit -Ereignis von default.aspx, um die URL und den Querystring neu zu schreiben, was in der Anfrage übergeben wurde (dh der Ort, der nicht existiert).

Zum Beispiel, ich fordere "/ somepage /? X = y" (was nicht existiert).

a) Web.config Regel bildet sie

b /Default.aspx) Page_PreInit es umschreibt zurück zu "/ somepage /? X = y". Das Ergebnis davon in IIS 7 (Express und Produktion) ist, dass das Serverprotokoll "/ somepage" für den Stub und "x = y" für die Abfrage angibt und alle Eigenschaften des Request-Objekts die angeforderten (nicht existent) URL (was ich wollte).

Der einzige seltsame Effekt ist, in IIS Express wird das Protokollelement zweimal geschrieben. Dies geschieht jedoch nicht in der Produktion (Windows Server 2008 R2).