URL-Neuschreibung in ASP.NET

 

Scott Mitchell
4GuysFromRolla.com

März 2004

Gilt für:
   Microsoft® ASP.NET

Zusammenfassung: Untersucht, wie Dynamische URL-Neuschreibung mit Microsoft ASP.NET ausgeführt wird. Die URL-Neuschreibung ist der Vorgang, eine eingehende Webanforderung abzufangen und automatisch an eine andere URL umzuleiten. Erläutert die verschiedenen Techniken für die Implementierung von URL-Neuschreibungen und untersucht reale Szenarien der URL-Neuschreibung. (31 gedruckte Seiten)

Laden Sie den Quellcode für diesen Artikel herunter.

Inhalte

Einführung
Allgemeine Verwendungen der URL-Neuschreibung
Was geschieht, wenn eine Anforderung IIS erreicht
Implementieren der URL-Neuschreibung
Erstellen eines URL-Neuschreibungsmoduls
Ausführen einer einfachen URL-Neuschreibung mit dem URL-Neuschreibungsmodul
Erstellen wirklich "Hackable"-URLs
Zusammenfassung
Verwandte Bücher

Einführung

Nehmen Sie sich einen Moment Zeit, um einige der URLs auf Ihrer Website zu betrachten. Finden Sie URLs wie http://yoursite.com/info/dispEmployeeInfo.aspx?EmpID=459-099\&type=summary? Oder vielleicht haben Sie eine Reihe von Webseiten, die von einem Verzeichnis oder einer Website zu einer anderen verschoben wurden, was zu fehlerhaften Links für Besucher führt, die die alten URLs als Lesezeichen versehen haben. In diesem Artikel sehen wir uns die Verwendung von URL-Neuschreibungen an, um diese hässlichen URLs auf aussagekräftige, unvergessliche URLs zu kürzen, indem typhttp://yoursite.com/info/dispEmployeeInfo.aspx?EmpID=459-099\&=zusammenfassung durch etwas wie etwa http://yoursite.com/people/sales/chuck.smithersetzt wird. Außerdem wird gezeigt, wie die URL-Neuschreibung verwendet werden kann, um einen intelligenten 404-Fehler zu erstellen.

DIE URL-Neuschreibung ist der Prozess des Abfangens einer eingehenden Webanforderung und umleiten der Anforderung an eine andere Ressource. Bei der Durchführung der URL-Neuschreibung wird die angeforderte URL in der Regel überprüft, und basierend auf dem Wert wird die Anforderung an eine andere URL umgeleitet. Wenn beispielsweise eine Websiteumstrukturierung dazu führte, dass alle Webseiten im Verzeichnis "/people/" in ein Verzeichnis "/info/employees/" verschoben wurden, sollten Sie die URL-Neuschreibung verwenden, um zu überprüfen, ob eine Webanforderung für eine Datei im Verzeichnis /people/ vorgesehen war. Wenn die Anforderung für eine Datei im Verzeichnis "/people/" angegeben wurde, möchten Sie die Anforderung automatisch an dieselbe Datei umleiten, sondern stattdessen im Verzeichnis /info/employees/directory.

Mit klassischem ASP bestand die einzige Möglichkeit zum Verwenden der URL-Neuschreibung darin, einen ISAPI-Filter zu schreiben oder ein Drittanbieterprodukt zu kaufen, das URL-Neuschreibungsfunktionen bietet. Mit Microsoft® ASP.NET können Sie jedoch ganz einfach ihre eigene URL-Umschreibungssoftware auf verschiedene Arten erstellen. In diesem Artikel werden wir die Techniken untersuchen, die für ASP.NET Entwickler für die Implementierung von URL-Neuschreibungen verfügbar sind, und dann zu einigen realen Verwendungen der URL-Neuschreibung wechseln. Bevor wir uns mit den technologischen Besonderheiten der URL-Neuschreibung befassen, werfen wir zunächst einen Blick auf einige alltägliche Szenarien, in denen die URL-Neuschreibung eingesetzt werden kann.

Allgemeine Verwendungen der URL-Neuschreibung

Das Erstellen von datengesteuerten ASP.NET Websites führt häufig zu einer einzelnen Webseite, die eine Teilmenge der Daten der Datenbank basierend auf Abfragezeichenfolgenparametern anzeigt. Wenn Sie beispielsweise eine E-Commerce-Website entwerfen, würde eine Ihrer Aufgaben es benutzern ermöglichen, durch die Produkte zum Verkauf zu navigieren. Um dies zu erleichtern, erstellen Sie möglicherweise eine Seite namens displayCategory.aspx, die die Produkte für eine bestimmte Kategorie anzeigt. Die anzuzeigenden Produkte der Kategorie würden durch einen Abfragezeichenfolgenparameter angegeben. Das heißt, wenn der Benutzer die Widgets zum Verkauf durchsuchen wollte, und alle Widgets hatten eine CategoryID von 5, würde der Benutzer folgendes besuchen: http://yousite.com/displayCategory.aspx?CategoryID=5

Es gibt zwei Nachteile zum Erstellen einer Website mit solchen URLs. Erstens ist die URL http://yousite.com/displayCategory.aspx?CategoryID=5 aus Sicht des Endbenutzers ein Unordnung. Benutzerfreundlichkeitsexperte Jakob Neilsenempfiehlt , URLs zu wählen, damit sie:

  • Sind kurz.
  • Sind einfach einzugeben.
  • Visualisieren Sie die Websitestruktur.
  • "Hackable", sodass der Benutzer über die Website navigiert, indem er Teile der URL abhackt.

Ich würde dieser Liste hinzufügen, dass URLs auch leicht zu merken sein sollten. Die URL http://yousite.com/displayCategory.aspx?CategoryID=5 erfüllt weder die Kriterien von Neilsen noch ist es einfach zu merken. Wenn Benutzer aufgefordert werden, in Abfragezeichenfolgenwerte einzugeben, wird eine URL schwer eingegeben und die URL nur von erfahrenen Webentwicklern "hackbar" erstellt, die über ein Verständnis des Zwecks von Abfragezeichenfolgenparametern und deren Name/Wertpaarstruktur verfügen.

Ein besserer Ansatz besteht darin, eine sensible, unvergessliche URL zu ermöglichen, z http://yoursite.com/products/Widgets. B. . Indem Sie einfach die URL betrachten, können Sie ableiten, was angezeigt wird – Informationen zu Widgets. Die URL ist auch einfach zu merken und zu teilen. Ich kann meinem Kollegen sagen: "Auschecken yoursite.com/products/Widgets", und sie kann wahrscheinlich die Seite aufrufen, ohne mich erneut fragen zu müssen, was die URL war. (Versuchen Sie es mit einer Amazon.com Seite!) Die URL wird auch angezeigt und sollte sich "hackbar" verhalten. Das heißt, wenn der Benutzer das Ende der URL hackt und typen in http://yoursite.com/products, sollte eine Auflistung aller Produkte oder mindestens eine Auflistung aller Kategorien von Produkten angezeigt werden, die sie anzeigen können.

Hinweis Betrachten Sie für ein hauptbeispiel einer "hackbaren" URL die URLs, die von vielen Blogmodulen generiert werden. Um die Beiträge für den 28. Januar 2004 anzuzeigen, besucht man eine URL wie http://someblog.com/2004/01/28. Wenn die URL gehackt http://someblog.com/2004/01wird, wird der Benutzer alle Beiträge für Januar 2004 sehen. Wenn Sie sie weiter http://someblog.com/2004 reduzieren, werden alle Beiträge für das Jahr 2004 angezeigt.

Zusätzlich zur Vereinfachung von URLs wird die URL-Neuschreibung häufig zum Behandeln von Websiteumstrukturierungen verwendet, die sonst zu zahlreichen fehlerhaften Links und veralteten Lesezeichen führen würden.

Was geschieht, wenn eine Anforderung IIS erreicht

Bevor wir genau untersuchen, wie die URL-Neuschreibung implementiert wird, ist es wichtig, dass wir ein Verständnis dafür haben, wie eingehende Anforderungen von Microsoft® Internetinformationsdienste (IIS) behandelt werden. Wenn eine Anforderung an einen IIS-Webserver gelangt, überprüft IIS die Erweiterung der angeforderten Datei, um zu bestimmen, wie die Anforderung behandelt wird. Anforderungen können nativ von IIS verarbeitet werden– wie HTML-Seiten, Bilder und andere statische Inhalte – oder IIS kann die Anforderung an eine ISAPI-Erweiterung weiterleiten. (Eine ISAPI-Erweiterung ist eine nicht verwaltete, kompilierte Klasse, die eine eingehende Webanforderung behandelt. Seine Aufgabe besteht darin, den Inhalt für die angeforderte Ressource zu generieren.)

Wenn z. B. eine Anforderung für eine Webseite namens Info.asp eingeht, leitet IIS die Nachricht an die asp.dll ISAPI-Erweiterung weiter. Diese ISAPI-Erweiterung lädt dann die angeforderte ASP-Seite, führt sie aus und gibt den gerenderten HTML-Code an IIS zurück, der sie dann an den angeforderten Client zurücksendet. Für ASP.NET Seiten leitet IIS die Nachricht an die aspnet_isapi.dll ISAPI-Erweiterung weiter. Die aspnet_isapi.dll ISAPI-Erweiterung übergibt dann die Verarbeitung an den verwalteten ASP.NET-Arbeitsprozess, der die Anforderung verarbeitet, und gibt den gerenderten HTML-Code der ASP.NET Webseite zurück.

Sie können IIS anpassen, um anzugeben, welche Erweiterungen den ISAPI-Erweiterungen zugeordnet sind. Abbildung 1 zeigt das Dialogfeld "Anwendungskonfiguration" aus dem Internetinformationsdienste Verwaltungstool. Beachten Sie, dass die ASP.NET-bezogenen Erweiterungen – .aspx, ASCX, .config, .asmx, .rem, .cs, .vb und andere – der aspnet_isapi.dll ISAPI-Erweiterung zugeordnet sind.

ms972974.urlrewriting_fig01(en-us,MSDN.10).gif

Abbildung 1. Konfigurierte Zuordnungen für Dateierweiterungen

Eine gründliche Diskussion darüber, wie IIS eingehende Anforderungen verwaltet, ist etwas über den Umfang dieses Artikels hinaus. Eine großartige, ausführliche Diskussion finden Sie jedoch in Michele Leroux Bustamantes Artikel Inside IIS und ASP.NET. Es ist wichtig zu verstehen, dass das ASP.NET-Modul nur eingehende Webanforderungen erhält, deren Erweiterungen explizit der aspnet_isapi.dll in IIS zugeordnet sind.

Untersuchen von Anforderungen mit ISAPI-Filtern

Zusätzlich zur Zuordnung der Dateierweiterung der eingehenden Webanforderung zur entsprechenden ISAPI-Erweiterung führt IIS auch eine Reihe anderer Aufgaben aus. Iis versucht beispielsweise, den Benutzer zu authentifizieren, der die Anforderung vornimmt, und bestimmt, ob der authentifizierte Benutzer über eine Autorisierung für den Zugriff auf die angeforderte Datei verfügt. Während der Lebensdauer der Behandlung einer Anforderung durchläuft IIS mehrere Zustände. In jedem Zustand löst IIS ein Ereignis aus, das programmgesteuert mithilfe von ISAPI-Filtern behandelt werden kann.

Wie ISAPI-Erweiterungen sind ISAPI-Filter Blöcke von nicht verwaltetem Code, der auf dem Webserver installiert ist. ISAPI-Erweiterungen sind so konzipiert, dass die Antwort für eine Anforderung an einen bestimmten Dateityp generiert wird. ISAPI-Filter enthalten dagegen Code, um auf Ereignisse zu reagieren, die von IIS ausgelöst werden. ISAPI-Filter können die eingehenden und ausgehenden Daten abfangen und sogar ändern. ISAPI-Filter verfügen über zahlreiche Anwendungen, darunter:

  • Authentifizierung und Autorisierung:
  • Protokollierung und Überwachung.
  • HTTP-Komprimierung.
  • URL-Neuschreibung.

Während ISAPI-Filter zum Erstellen von URL-Neuschreibungen verwendet werden können, untersucht dieser Artikel die Implementierung von URL-Neuschreibungen mithilfe von ASP.NET. Wir werden jedoch die Tradeoffs zwischen der Implementierung der URL-Neuschreibung als ISAPI-Filter und der Verwendung von Techniken diskutieren, die in ASP.NET verfügbar sind.

Was geschieht, wenn eine Anforderung das ASP.NET Modul eingibt

Vor ASP.NET müssen URL-Neuschreibungen auf IIS-Webservern mithilfe eines ISAPI-Filters implementiert werden. Die URL-Umschreibung ist mit ASP.NET möglich, da das ASP.NET-Modul auffällig ähnlich wie IIS ist. Die Ähnlichkeiten entstehen, weil der ASP.NET Motor:

  1. Löst Ereignisse aus, während sie eine Anforderung verarbeitet.
  2. Ermöglicht eine beliebige Anzahl von HTTP-Modulen die ausgelösten Ereignisse, ähnlich den ISAPI-Filtern von IIS.
  3. Stellvertretungen, die die angeforderte Ressource in einen HTTP-Handler rendern, was den ISAPI-Erweiterungen von IIS entspricht.

Wie IIS löst die ASP.NET Engine während der Lebensdauer der Anforderung Ereignisse aus, die ihre Änderung von einem Verarbeitungszustand in einen anderen signalisieren. Das BeginRequest-Ereignis wird beispielsweise ausgelöst, wenn das ASP.NET-Modul zuerst auf eine Anforderung antwortet. Das AuthenticateRequest-Ereignis wird als nächstes ausgelöst, was auftritt, wenn die Identität des Benutzers eingerichtet wurde. (Es gibt zahlreiche weitere Ereignisse – AuthorizeRequest, ResolveRequestCache und EndRequest, unter anderem. Diese Ereignisse sind Ereignisse der System.Web.HttpApplication-Klasse ; weitere Informationen finden Sie in der technischen Dokumentation zur HttpApplication-Klasse .)

Wie im vorherigen Abschnitt erläutert, können ISAPI-Filter erstellt werden, um auf die von IIS ausgelösten Ereignisse zu reagieren. In ähnlicher Weise stellt ASP.NET HTTP-Module bereit, die auf die vom ASP.NET-Modul ausgelösten Ereignisse reagieren können. Eine ASP.NET Webanwendung kann so konfiguriert werden, dass mehrere HTTP-Module vorhanden sind. Für jede vom ASP.NET-Modul verarbeitete Anforderung wird jedes konfigurierte HTTP-Modul initialisiert und kann Ereignishandler während der Verarbeitung der Anforderung an die Ereignisse verkabeln, die während der Verarbeitung der Anforderung ausgelöst werden. Stellen Sie sicher, dass für jede Anforderung eine Reihe integrierter HTTP-Module verwendet wird. Eines der integrierten HTTP-Module ist das FormsAuthenticationModule, das zuerst überprüft, ob die Formularauthentifizierung verwendet wird und ob der Benutzer authentifiziert ist oder nicht. Wenn nicht, wird der Benutzer automatisch auf die angegebene Anmeldeseite umgeleitet.

Erinnern Sie sich daran, dass eine eingehende Anforderung mit IIS schließlich an eine ISAPI-Erweiterung weitergeleitet wird, deren Auftrag es ist, die Daten für die jeweilige Anforderung zurückzugeben. Wenn beispielsweise eine Anforderung für eine klassische ASP-Webseite eingeht, übergibt IIS die Anforderung an die asp.dll ISAPI-Erweiterung, deren Aufgabe es ist, das HTML-Markup für die angeforderte ASP-Seite zurückzugeben. Das ASP.NET Modul nutzt einen ähnlichen Ansatz. Nach der Initialisierung der HTTP-Module besteht die nächste Aufgabe des ASP.NET-Moduls darin, zu bestimmen, welche HTTP-Handler die Anforderung verarbeiten soll.

Alle Anforderungen, die das ASP.NET Modul übergeben, kommen schließlich zu einem HTTP-Handler oder einer HTTP-Handlerfabrik (eine HTTP-Handlerfabrik gibt einfach eine Instanz eines HTTP-Handlers zurück, der dann zum Verarbeiten der Anforderung verwendet wird). Der endgültige HTTP-Handler rendert die angeforderte Ressource und gibt die Antwort zurück. Diese Antwort wird an IIS zurückgesendet, die ihn dann an den Benutzer zurückgibt, der die Anforderung gestellt hat.

ASP.NET enthält eine Reihe integrierter HTTP-Handler. Die PageHandlerFactory wird beispielsweise verwendet, um ASP.NET Webseiten zu rendern. Die WebServiceHandlerFactory wird zum Rendern der SOAP-Umschläge für ASP.NET Webdienste verwendet. Der TraceHandler rendert das HTML-Markup für Anforderungen an trace.axd.

Abbildung 2 veranschaulicht, wie eine Anforderung für eine ASP.NET Ressource behandelt wird. Zunächst empfängt IIS die Anforderung und verteilt sie an aspnet_isapi.dll. Als Nächstes initialisiert das ASP.NET-Modul die konfigurierten HTTP-Module. Schließlich wird der richtige HTTP-Handler aufgerufen, und die angeforderte Ressource wird gerendert, das generierte Markup zurück an IIS und zurück an den angeforderten Client zurückgegeben.

ms972974.urlrewriting_fig02(en-us,MSDN.10).gif

Abbildung 2. Anfordern der Verarbeitung durch IIS und ASP.NET

Erstellen und Registrieren benutzerdefinierter HTTP-Module und HTTP-Handler

Das Erstellen benutzerdefinierter HTTP-Module und HTTP-Handler sind relativ einfache Aufgaben, die eine verwaltete Klasse umfassen, die die richtige Schnittstelle implementiert. HTTP-Module müssen die System.Web.IHttpModule-Schnittstelle implementieren, während HTTP-Handler und HTTP-Handler-Fabriken die System.Web.IHttpHandler-Schnittstelle und die System.Web.IHttpHandlerFactory-Schnittstelle implementieren müssen. Die Besonderheiten der Erstellung von HTTP-Handlern und HTTP-Modulen sind über den Umfang dieses Artikels hinaus. Lesen Sie für einen guten Hintergrund mansoor Ahmed Siddiquis Artikel, HTTP-Handler und HTTP-Module in ASP.NET.

Nachdem ein benutzerdefinierter HTTP-Modul oder HTTP-Handler erstellt wurde, muss er bei der Webanwendung registriert werden. Das Registrieren von HTTP-Modulen und HTTP-Handlern für einen gesamten Webserver erfordert nur eine einfache Ergänzung zur machine.config Datei; Das Registrieren eines HTTP-Moduls oder HTTP-Handlers für eine bestimmte Webanwendung umfasst das Hinzufügen einiger XML-Zeilen zur Web.config Datei der Anwendung.

Fügen Sie insbesondere zum Hinzufügen eines HTTP-Moduls zu einer Webanwendung die folgenden Zeilen im Abschnitt "Configuration/system.web" des Web.config hinzu:

<httpModules>
   <add type="type" name="name" />
</httpModules>

Der Typwert stellt den Assembly- und Klassennamen des HTTP-Moduls bereit, während der Namewert einen Anzeigenamen bereitstellt, mit dem das HTTP-Modul in der Datei "Global.asax" bezeichnet werden kann.

HTTP-Handler und HTTP-Handler-Fabriken werden vom <httpHandlers-Tag> im Konfigurations-/System.Web-Abschnitt des Web.config konfiguriert, z. B.:

<httpHandlers>
   <add verb="verb" path="path" type="type" />
</httpHandlers>

Erinnern Sie sich daran, dass für jede eingehende Anforderung das ASP.NET-Modul bestimmt, welche HTTP-Handler zum Rendern der Anforderung verwendet werden sollen. Diese Entscheidung wird basierend auf dem Eingehenden Anforderungsverb und Pfad getroffen. Das Verb gibt an, welche Art von HTTP-Anforderung vorgenommen wurde – GET oder POST –, während der Pfad den Speicherort und den Dateinamen der angeforderten Datei angibt. Wenn wir also über einen HTTP-Handler verfügen möchten, der alle Anforderungen – entweder GET oder POST – für Dateien mit der SCOTT-Erweiterung behandelt, fügen wir der Web.config-Datei Folgendes hinzu:

<httpHandlers>
   <add verb="*" path="*.scott" type="type" />
</httpHandlers>

dabei war der Typ unseres HTTP-Handlers.

Hinweis Bei der Registrierung von HTTP-Handlern ist es wichtig, sicherzustellen, dass die vom HTTP-Handler verwendeten Erweiterungen in IIS dem ASP.NET-Modul zugeordnet werden. Das heißt, wenn die SCOTT-Erweiterung in IIS nicht der aspnet_isapi.dll ISAPI-Erweiterung zugeordnet ist, führt eine Anforderung für die Datei foo.scott dazu, dass IIS versucht, den Inhalt der Datei foo.scott zurückzugeben. Damit der HTTP-Handler diese Anforderung verarbeiten kann, muss die Scott-Erweiterung dem ASP.NET-Modul zugeordnet werden. Anschließend leitet das ASP.NET Modul die Anforderung ordnungsgemäß an den entsprechenden HTTP-Handler weiter.

Weitere Informationen zum Registrieren von HTTP-Modulen und HTTP-Handlern finden Sie in der <HttpModules-Elementdokumentation> zusammen mit der <HttpHandlers-Elementdokumentation>.

Implementieren der URL-Neuschreibung

Url-Neuschreibung kann entweder mit ISAPI-Filtern auf IIS-Webserverebene oder mit HTTP-Modulen oder HTTP-Handlern auf ASP.NET Ebene implementiert werden. Dieser Artikel konzentriert sich auf die Implementierung von URL-Neuschreibungen mit ASP.NET, sodass wir nicht in die Besonderheiten der Implementierung von URL-Neuschreibungen mit ISAPI-Filtern einsteigen.

Die Implementierung der URL-Neuschreibung auf ASP.NET Ebene ist über die RewritePath() -Methode der System.Web.HttpContext-Klasse möglich. Die HttpContext-Klasse enthält HTTP-spezifische Informationen zu einer bestimmten HTTP-Anforderung. Bei jeder Vom ASP.NET-Modul empfangenen Anforderung wird für diese Anforderung eine HttpContext-Instanz erstellt. Diese Klasse verfügt über Eigenschaften wie: Anforderung und Antwort, die Zugriff auf die eingehende Anforderung und ausgehende Antwort bieten; Anwendung und Sitzung, die Zugriff auf Anwendungs- und Sitzungsvariablen bieten; Benutzer, der Informationen über den authentifizierten Benutzer bereitstellt; und andere verwandte Eigenschaften.

Mit der Microsoft® .NET Framework Version 1.0 akzeptiert die RewritePath()-Methode eine einzelne Zeichenfolge, den neuen zu verwendenden Pfad. Intern aktualisiert die RewritePath(string)-Methode der HttpContext-Klasse die Path- und QueryString-Eigenschaften des Request-Objekts. Zusätzlich zu RewritePath(string) enthält die .NET Framework Version 1.1 eine andere Form der RewritePath() -Methode, die drei Zeichenfolgeneingabeparameter akzeptiert. Dieses alternative überladene Formular legt nicht nur die Path- und QueryString-Eigenschaften des Request-Objekts fest, sondern legt auch interne Membervariablen fest, die zum Berechnen der Werte des Request-Objekts für die Eigenschaften PhysicalPath, PathInfo und FilePath verwendet werden.

Um die URL-Neuschreibung in ASP.NET zu implementieren, müssen wir dann ein HTTP-Modul oder http-Handler erstellen, der:

  1. Überprüft den angeforderten Pfad, um festzustellen, ob die URL neu geschrieben werden muss.
  2. Schreibt den Pfad bei Bedarf neu, indem er die RewritePath() -Methode aufruft.

Stellen Sie sich beispielsweise vor, dass unsere Website informationen für jeden Mitarbeiter hatte, auf die über /info/employee.aspx?empID=employeeID=employeeID zugegriffen werden kann. Um die URLs zu "hackfähiger" zu machen, können wir entscheiden, dass Mitarbeiterseiten zugänglich sind: /people/EmployeeName.aspx. Hier ist ein Fall, in dem die URL-Neuschreibung verwendet werden soll. Wenn die Seite /people/ScottMitchell.aspx angefordert wurde, sollten wir stattdessen die URL neu schreiben, damit stattdessen die Seite /info/employee.aspx?empID=1001 verwendet wurde.

URL-Neuschreibung mit HTTP-Modulen

Beim Durchführen der URL-Neuschreibung auf ASP.NET Ebene können Sie entweder ein HTTP-Modul oder einen HTTP-Handler verwenden, um die Neuschreibung auszuführen. Wenn Sie ein HTTP-Modul verwenden, müssen Sie entscheiden, an welcher Stelle während des Lebenszyklus der Anforderung überprüft wird, ob die URL neu geschrieben werden muss. Auf den ersten Blick scheint dies eine beliebige Wahl zu sein, aber die Entscheidung kann ihre Anwendung auf erhebliche und subtile Weise beeinflussen. Die Wahl, wo die Neuschreibung ausgeführt werden soll, weil die integrierten ASP.NET HTTP-Module die Eigenschaften des Request-Objekts verwenden, um ihre Aufgaben auszuführen. (Erinnern Sie sich daran, dass das Neuschreiben des Pfads die Eigenschaftswerte des Request-Objekts ändert.) Diese integrierten HTTP-Module und die Ereignisse, an die sie gebunden sind, sind unten aufgeführt:

HTTP-Modul Event Beschreibung
Formsauthenticationmodule Authenticaterequest Bestimmt, ob der Benutzer mithilfe der Formularauthentifizierung authentifiziert wird. Wenn nicht, wird der Benutzer automatisch auf die angegebene Anmeldeseite umgeleitet.
FileAuthorizationMoudle Authorizerequest Bei verwendung von Windows-Authentifizierung überprüft dieses HTTP-Modul, um sicherzustellen, dass das Microsoft® Windows-Konto ® über ausreichende Rechte für die angeforderte Ressource verfügt.
Urlauthorizationmodule Authorizerequest Überprüft, ob der Anforderer auf die angegebene URL zugreifen kann. Die URL-Autorisierung wird über die <Autorisierungs> - und <Speicherortelemente> in der datei Web.config angegeben.

Erinnern Sie sich daran, dass das BeginRequest-Ereignis vor AuthenticateRequest ausgelöst wird, das vor AuthorizeRequest ausgelöst wird.

Ein sicherer Ort, an dem die URL-Neuschreibung ausgeführt werden kann, befindet sich im BeginRequest-Ereignis . Das bedeutet, dass die URL, wenn die URL neu geschrieben werden muss, zum Zeitpunkt der Ausführung eines der integrierten HTTP-Module ausgeführt wird. Der Nachteil dieser Vorgehensweise entsteht beim Verwenden der Formularauthentifizierung. Wenn Sie die Formularauthentifizierung zuvor verwendet haben, wissen Sie, dass der Benutzer, wenn er eine eingeschränkte Ressource besucht, automatisch an eine angegebene Anmeldeseite umgeleitet wird. Nach der erfolgreichen Anmeldung wird der Benutzer an die Seite zurückgesendet, auf die er versucht hat, zuerst darauf zuzugreifen.

Wenn die URL-Neuschreibung in den BeginRequest - oder AuthenticateRequest-Ereignissen ausgeführt wird, leitet die Anmeldeseite beim Übermitteln den Benutzer an die neu geschriebene Seite um. Stellen Sie sich also vor, dass ein Benutzer in sein Browserfenster /people/ScottMitchell.aspx eingibt, das in /info/employee.aspx?empID=1001 umgeschrieben wird. Wenn die Webanwendung so konfiguriert ist, dass die Formularauthentifizierung verwendet wird, wenn der Benutzer zuerst /people/ScottMitchell.aspx besucht, wird zuerst die URL in /info/employee.aspx?empID=1001 neu geschrieben; Als Nächstes wird das FormsAuthenticationModule-Programm ausgeführt, wobei der Benutzer bei Bedarf zur Anmeldeseite umgeleitet wird. Die URL, an die der Benutzer gesendet wird, nachdem er sich erfolgreich angemeldet hat, lautet jedoch "/info/employee.aspx?empID=1001", da dies die URL der Anforderung war, als die FormsAuthenticationModule ausgeführt wurde.

Ebenso sieht die UrlAuthorizationModule bei der Neuschreibung in den BeginRequest- oder AuthenticateRequest-Ereignissen die neu geschriebene URL. Das bedeutet, dass Sie bei Verwendung <von Speicherortelementen> in Ihrer Web.config-Datei die Autorisierung für bestimmte URLs angeben, müssen Sie auf die neu geschriebene URL verweisen.

Um diese Subtilität zu beheben, können Sie sich entscheiden, die URL-Neuschreibung im AuthorizeRequest-Ereignis auszuführen. Während dieser Ansatz die URL-Autorisierungs- und Formularauthentifizierungsanomalien korrigiert, wird eine neue Falten eingeführt: Die Dateiberechtigung funktioniert nicht mehr. Wenn Sie Windows-Authentifizierung verwenden, überprüft das FileAuthorizationModule, um sicherzustellen, dass der authentifizierte Benutzer über die entsprechenden Zugriffsrechte verfügt, um auf die bestimmte ASP.NET Seite zuzugreifen.

Imagine, wenn ein Satz von Benutzern keinen Windows-Ebene-Dateizugriff auf C:\Inetput\wwwroot\info\employee.aspx hat; wenn solche Benutzer versuchen, /info/employee.aspx?empID=1001 zu besuchen, erhalten sie einen Autorisierungsfehler. Wenn wir jedoch die URL-Neuschreibung in das AuthenticateRequest-Ereignis verschieben, wenn die FileAuthorizationModule die Sicherheitseinstellungen überprüft, denkt sie weiterhin, dass die angeforderte Datei /people/ScottMitchell.aspx ist, da die URL noch neu geschrieben werden muss. Daher wird die Dateiberechtigungsprüfung übergeben, damit dieser Benutzer den Inhalt der neu geschriebenen URL, /info/employee.aspx?empID=1001 anzeigen kann.

Wann sollte die URL-Neuschreibung in einem HTTP-Modul ausgeführt werden? Es hängt davon ab, welche Art der Authentifizierung Sie verwenden. Wenn Sie keine Authentifizierung verwenden, ist es nicht wichtig, ob die URL-Neuschreibung in BeginRequest, AuthenticationRequest oder AuthorizeRequest erfolgt. Wenn Sie die Formularauthentifizierung verwenden und Windows-Authentifizierung nicht verwenden, platzieren Sie die URL-Neuschreibung im AuthorizeRequest-Ereignishandler. Wenn Sie Windows-Authentifizierung verwenden, planen Sie die URL-Neuschreibung während der BeginRequest- oder AuthenticateRequest-Ereignisse.

URL-Neuschreibung in HTTP-Handlern

Die URL-Neuschreibung kann auch von einer HTTP-Handler- oder HTTP-Handler-Fabrik ausgeführt werden. Erinnern Sie sich daran, dass ein HTTP-Handler eine Klasse ist, die für das Generieren des Inhalts für einen bestimmten Anforderungstyp verantwortlich ist; eine HTTP-Handlerfabrik ist eine Klasse, die für die Rückgabe einer Instanz eines HTTP-Handlers verantwortlich ist, die den Inhalt für einen bestimmten Anforderungstyp generieren kann.

In diesem Artikel sehen wir uns das Erstellen einer URL-Neuschreibungs-HTTP-Handler-Fabrik für ASP.NET Webseiten an. HTTP-Handler-Factories müssen die IHttpHandlerFactory-Schnittstelle implementieren, die eine GetHandler() -Methode enthält. Nach der Initialisierung der entsprechenden HTTP-Module bestimmt das ASP.NET-Modul, welche HTTP-Handler- oder HTTP-Handler-Fabrik für die angegebene Anforderung aufgerufen werden soll. Wenn eine HTTP-Handler-Factory aufgerufen werden soll, ruft das ASP.NET-Modul die GETHandler() -Methode des HTTP-Handlers auf, die in der HttpContext für die Webanforderung übergeben wird, zusammen mit einigen anderen Informationen. Die HTTP-Handler-Fabrik muss dann ein Objekt zurückgeben, das IHttpHandler implementiert, der die Anforderung verarbeiten kann.

Um die URL-Neuschreibung über einen HTTP-Handler auszuführen, können wir eine HTTP-Handler-Fabrik erstellen, deren GetHandler() -Methode den angeforderten Pfad überprüft, um festzustellen, ob es neu geschrieben werden muss. Wenn dies der Fall ist, kann er die übergebene HttpContext-Methode des RewritePath() -Objekts aufrufen, wie zuvor erläutert. Schließlich kann die HTTP-Handler factory den HTTP-Handler zurückgeben, der von der Methode "GetCompiledPageInstance() der GetCompiledPageInstance()"-Klasse der System.Web.UI.PageParser-Klasse zurückgegeben wird. (Dies ist die gleiche Technik, mit der die integrierte ASP.NET-Website HTTP-Handler-Fabrik, PageHandlerFactory, funktioniert.)

Da alle HTTP-Module vor der Instanziierung der benutzerdefinierten HTTP-Handler-Fabrik initialisiert wurden, stellt die Verwendung einer HTTP-Handler-Factory die gleichen Herausforderungen dar, wenn die URL-Neuschreibung in den letzten Phasen der Ereignisse platziert wird – nämlich die Dateiberechtigung funktioniert nicht. Wenn Sie sich also auf Windows-Authentifizierung und Dateiberechtigung verlassen, möchten Sie den HTTP-Modulansatz für die URL-Neuschreibung verwenden.

Im nächsten Abschnitt sehen wir uns das Erstellen eines wiederverwendbaren URL-Neuschreibungsmoduls an. Nach unserer Prüfung des URL-Neuschreibungsmoduls – das im Codedownload dieses Artikels verfügbar ist – verbringen wir die restlichen beiden Abschnitte, die reale Verwendung von URL-Neuschreibungen untersuchen. Zunächst sehen wir uns an, wie Sie das URL-Neuschreibungsmodul verwenden und ein einfaches BEISPIEL für die URL-Neuschreibung betrachten. Danach nutzen wir die Leistungsfähigkeit der regulären Ausdrucksfunktionen des Neuschreibungsmoduls, um wirklich "hackbare" URLs bereitzustellen.

Erstellen eines URL-Neuschreibungsmoduls

Um zu veranschaulichen, wie die URL-Neuschreibung in einer ASP.NET-Webanwendung implementiert wird, habe ich ein URL-Neuschreibungsmodul erstellt. Dieses Umschreibenmodul bietet die folgenden Funktionen:

  • Der ASP.NET Seitenentwickler, der das URL-Neuschreibungsmodul verwendet, kann die Neuschreibungsregeln in der Web.config-Datei angeben.
  • Die Neuschreibungsregeln können reguläre Ausdrücke verwenden, um leistungsstarke Neuschreibungsregeln zu ermöglichen.
  • Die URL-Neuschreibung kann einfach konfiguriert werden, um ein HTTP-Modul oder einen HTTP-Handler zu verwenden.

In diesem Artikel werden wir die URL-Neuschreibung mit nur dem HTTP-Modul untersuchen. Um zu sehen, wie HTTP-Handler zum Ausführen der URL-Neuschreibung verwendet werden können, lesen Sie den code, der für den Download mit diesem Artikel verfügbar ist.

Angeben von Konfigurationsinformationen für das URL-Neuschreibungsmodul

Untersuchen wir die Struktur der Neuschreibungsregeln in der Web.config Datei. Zunächst müssen Sie in der Web.config Datei angeben, ob Sie die URL-Neuschreibung mit dem HTTP-Modul oder dem HTTP-Handler ausführen möchten. Im Download enthält die Web.config-Datei zwei Einträge, die auskommentiert wurden:

<!--
<httpModules>
   <add type="URLRewriter.ModuleRewriter, URLRewriter" 
        name="ModuleRewriter" />
</httpModules>
-->

<!--
<httpHandlers>
   <add verb="*" path="*.aspx" 
        type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
</httpHandlers>
-->

Kommentieren Sie den <httpModules-Eintrag> , um das HTTP-Modul zum Neuschreiben zu verwenden; kommentieren Sie stattdessen den <httpHandler-Eintrag> , um den HTTP-Handler für die Neuschreibung zu verwenden.

Zusätzlich zum Angeben, ob das HTTP-Modul oder der HTTP-Handler zum Neuschreiben verwendet wird, enthält die Web.config-Datei die Neuschreibungsregeln. Eine Neuschreibungsregel besteht aus zwei Zeichenfolgen: das Muster, nach dem in der angeforderten URL gesucht werden soll, und die Zeichenfolge, mit der das Muster ersetzt werden soll, falls gefunden. Diese Informationen werden in der Web.config Datei mit der folgenden Syntax ausgedrückt:

<RewriterConfig>
   <Rules>
   <RewriterRule>
      <LookFor>pattern to look for</LookFor>
      <SendTo>string to replace pattern with</SendTo>
   </RewriterRule>
   <RewriterRule>
      <LookFor>pattern to look for</LookFor>
      <SendTo>string to replace pattern with</SendTo>
   </RewriterRule>
   ...
   </Rules>
</RewriterConfig>

Jede Rewrite-Regel wird durch ein <RewriterRule-Element> ausgedrückt. Das zu suchende Muster wird vom LookFor-Element> angegeben, während die Zeichenfolge zum Ersetzen des gefundenen Musters in das<<SentTo-Element> eingegeben wird. Diese Neuschreibungsregeln werden von oben bis unten ausgewertet. Wenn eine Übereinstimmung gefunden wird, wird die URL neu geschrieben und die Suche durch die Neuschreibungsregeln beendet.

Wenn Sie Muster im <LookFor-Element> angeben, erkennen Sie, dass reguläre Ausdrücke verwendet werden, um die übereinstimmungs- und Zeichenfolgenersetzung auszuführen. (In einem bit, wir sehen uns ein reales Beispiel an, das veranschaulicht, wie Sie mit regulären Ausdrücken nach einem Muster suchen.) Da das Muster ein regulärer Ausdruck ist, müssen Sie alle Zeichen entwischen, die reservierte Zeichen in regulären Ausdrücken sind. (Einige der reservierten Zeichen des regulären Ausdrucks umfassen: ., ?, ^, $, und andere. Dies kann durch vorangestellte Rückstriche wie \entwendbar sein. um einem Literalzeitraum zu entsprechen.)

URL-Neuschreiben mit einem HTTP-Modul

Das Erstellen eines HTTP-Moduls ist so einfach wie das Erstellen einer Klasse, die die IHttpModule-Schnittstelle implementiert. Die IHttpModule-Schnittstelle definiert zwei Methoden:

  • Init(HttpApplication). Diese Methode wird ausgelöst, wenn das HTTP-Modul initialisiert wird. In dieser Methode verkabeln Sie Ereignishandler an die entsprechenden HttpApplication-Ereignisse .
  • Dispose(). Diese Methode wird aufgerufen, wenn die Anforderung abgeschlossen und an IIS gesendet wurde. Alle endgültigen Bereinigungen sollten hier ausgeführt werden.

Um das Erstellen eines HTTP-Moduls für die URL-Neuschreibung zu erleichtern, begann ich mit dem Erstellen einer abstrakten Basisklasse, BaseModuleRewriter. Diese Klasse implementiert IHttpModule. Im Init()-Ereignis wird das Autorrequest-Ereignis von HttpApplication an die BaseModuleRewriter_AuthorizeRequest-Methode verkabelt. Die BaseModuleRewriter_AuthorizeRequest-Methode ruft die Rewrite() -Methode der Klasse auf, die in den angeforderten Path übergeben wird, zusammen mit dem HttpApplication-Objekt , das in die Init() -Methode übergeben wurde. Die Rewrite() -Methode ist abstrahiert, d. h. in der BaseModuleRewriter-Klasse hat die Rewrite() -Methode keinen Methodentext; Stattdessen muss die von BaseModuleRewriter abgeleitete Klasse diese Methode außer Kraft setzen und einen Methodentext bereitstellen.

Mit dieser Basisklasse müssen wir jetzt eine von BaseModuleRewriter abgeleitete Klasse erstellen, die Rewrite() überschreibt und die URL-Neuschreibungslogik dort ausführt. Der Code für BaseModuleRewriter wird unten angezeigt.

public abstract class BaseModuleRewriter : IHttpModule
{
   public virtual void Init(HttpApplication app)
   {
      // WARNING!  This does not work with Windows authentication!
      // If you are using Windows authentication, 
      // change to app.BeginRequest
      app.AuthorizeRequest += new 
         EventHandler(this.BaseModuleRewriter_AuthorizeRequest);
   }

   public virtual void Dispose() {}

   protected virtual void BaseModuleRewriter_AuthorizeRequest(
     object sender, EventArgs e)
   {
      HttpApplication app = (HttpApplication) sender;
      Rewrite(app.Request.Path, app);
   }

   protected abstract void Rewrite(string requestedPath, 
     HttpApplication app);
}

Beachten Sie, dass die BaseModuleRewriter-Klasse die URL-Neuschreibung im AuthorizeRequest-Ereignis ausführt. Erinnern Sie sich daran, dass Wenn Sie Windows-Authentifizierung mit Dateiberechtigung verwenden, müssen Sie dies ändern, sodass die URL-Neuschreibung entweder in den BeginRequest- oder AuthenticateRequest-Ereignissen ausgeführt wird.

Die ModuleRewriter-Klasse erweitert die BaseModuleRewriter-Klasse und ist verantwortlich für die Ausführung der tatsächlichen URL-Neuschreibung. ModuleRewriter enthält eine einzelne überschriebene Methode – Rewrite() –, die unten gezeigt wird:

protected override void Rewrite(string requestedPath, 
   System.Web.HttpApplication app)
{
   // get the configuration rules
   RewriterRuleCollection rules = 
     RewriterConfiguration.GetConfig().Rules;

   // iterate through each rule...
   for(int i = 0; i < rules.Count; i++)
   {
      // get the pattern to look for, and 
      // Resolve the Url (convert ~ into the appropriate directory)
      string lookFor = "^" + 
        RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, 
        rules[i].LookFor) + "$";

      // Create a regex (note that IgnoreCase is set...)
      Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

      // See if a match is found
      if (re.IsMatch(requestedPath))
      {
         // match found - do any replacement needed
         string sendToUrl = 
RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, 
            re.Replace(requestedPath, rules[i].SendTo));

         // Rewrite the URL
         RewriterUtils.RewriteUrl(app.Context, sendToUrl);
         break;      // exit the for loop
      }
   }
}

Die Rewrite() -Methode beginnt mit dem Abrufen der Satz von Neuschreibungsregeln aus der Web.config-Datei. Anschließend werden die neu geschriebenen Regeln gleichzeitig durchschrieben und für jede Regel die LookFor-Eigenschaft erfasst und ein regulärer Ausdruck verwendet, um festzustellen, ob eine Übereinstimmung in der angeforderten URL gefunden wird.

Wenn eine Übereinstimmung gefunden wird, wird ein regulärer Ausdruck auf dem angeforderten Pfad mit dem Wert der SendTo-Eigenschaft ausgeführt. Diese ersetzte URL wird dann an die RewriterUtils.RewriteUrl() -Methode übergeben. RewriterUtils ist eine Hilfsklasse, die einige statische Methoden bereitstellt, die sowohl vom URL-Neuschreiben von HTTP-Modul als auch vom HTTP-Handler verwendet werden. Die RewriterUrl() -Methode ruft einfach die RewriteUrl() -Methode des HttpContext-Objekts auf.

Hinweis Möglicherweise haben Sie bemerkt, dass beim Ausführen des regulären Ausdrucksgleichs und der Ersatz ein Aufruf von RewriterUtils.ResolveUrl() vorgenommen wird. Diese Hilfsmethode ersetzt einfach alle Instanzen in ~ der Zeichenfolge durch den Wert des Pfads der Anwendung.

Der gesamte Code für das URL-Neuschreibungsmodul steht für den Download mit diesem Artikel zur Verfügung. Wir haben die meisten deutschen Teile untersucht, aber es gibt auch andere Komponenten, z. B. Klassen zum Enterialisieren der XML-formatierten Neuschreibungsregeln in der Web.config-Datei in ein Objekt sowie die HTTP-Handler-Factory für die URL-Neuschreibung. Die verbleibenden drei Abschnitte dieses Artikels untersuchen reale Verwendungen von URL-Neuschreibungen.

Ausführen der einfachen URL-Neuschreibung mit dem URL-Rewriting-Modul

Um das URL-Neuschreibungsmodul in Aktion zu veranschaulichen, erstellen wir eine ASP.NET Webanwendung, die einfache URL-Neuschreibung verwendet. Imagine, dass wir für ein Unternehmen arbeiten, das sortierte Produkte online verkauft. Diese Produkte werden in die folgenden Kategorien unterteilt:

Kategorie-ID Kategoriename
1 Getränke
2 Gewürze
3 Confections
4 Dairy Products
... ...

Angenommen, wir haben bereits eine ASP.NET-Webseite namens ListProductsByCategory.aspx erstellt, die einen Kategorie-ID-Wert in der Abfragezeichenfolge akzeptiert und alle Produkte anzeigt, die zu dieser Kategorie gehören. So würden Benutzer, die unsere Getränke zum Verkauf anzeigen möchten, ListProductsByCategory.aspx besuchen? CategoryID=1, während Benutzer, die unsere Milchprodukte anzeigen möchten, ListProductsByCategory.aspx besuchen würden? CategoryID=4. Angenommen, wir haben eine Seite namens ListCategories.aspx, die die Kategorien von Produkten für den Verkauf enthält.

Dies ist eindeutig ein Fall für die URL-Neuschreibung, da die URLs, die ein Benutzer angezeigt wird, keine Bedeutung für den Benutzer tragen, oder sie bieten eine "Hackbarkeit". Stattdessen verwenden wir die URL-Neuschreibung, damit die URL, wenn ein Benutzer /Products/Beverages.aspx besucht, seine URL in ListProductsByCategory.aspx neu geschrieben wird? CategoryID=1. Dies können wir mit der folgenden URL-Neuschreibungsregel in der datei Web.config erreichen:

<RewriterConfig>
   <Rules>
      <!-- Rules for Product Lister -->
      <RewriterRule>
         <LookFor>~/Products/Beverages\.aspx</LookFor>
         <SendTo>~/ListProductsByCategory.aspx?CategoryID=1</SendTo>
      </RewriterRule>
      <RewriterRule>
   </Rules>
</RewriterConfig>

Wie Sie sehen können, sucht diese Regel, um festzustellen, ob der vom Benutzer angeforderte Pfad /Products/Beverages.aspx war. Wenn dies der Vorgang war, wird die URL als /ListProductsByCategory.aspx neu geschrieben? CategoryID=1.

Hinweis Beachten Sie, dass das <LookFor-Element> den Punkt in Beverages.aspx ausweicht. Dies liegt daran, dass der <LookFor-Wert> in einem regulären Ausdrucksmuster verwendet wird, und der Punkt ein Sonderzeichen in regulären Ausdrücken ist, was bedeutet, dass eine URL von /Products/BeveragesQaspx z. B. übereinstimmen würde. Durch Die Kapselung des Punkts (mit \.) geben wir an, dass wir einem Literalzeitraum entsprechen möchten, und nicht um ein altes Zeichen.

Wenn ein Benutzer /Products/Beverages.aspx besucht, werden die Getränke für den Verkauf angezeigt. Abbildung 3 zeigt einen Screenshot eines Browsers, der /Products/Beverages.aspx besucht. Beachten Sie, dass in der Adressleiste des Browsers die URL /Products/Beverages.aspx liest, aber der Benutzer sieht tatsächlich den Inhalt von ListProductsByCategory.aspx? CategoryID=1. (Tatsächlich gibt es nicht einmal eine /Products/Beverages.aspx-Datei auf dem Webserver!)

ms972974.urlrewriting_fig03(en-us,MSDN.10).gif

Abbildung 3. Anfordern einer Kategorie nach dem Neuschreiben der URL

Ähnlich wie /Products/Beverages.aspx, fügen wir als nächstes Neuschreibungsregeln für die anderen Produktkategorien hinzu. Dies umfasst einfach das Hinzufügen zusätzlicher <RewriterRule-Elemente> innerhalb des <Rules-Elements> in der datei Web.config. Lesen Sie die datei Web.config im Download, um den vollständigen Satz von Neuschreibungsregeln für die Demo zu erhalten.

Um die URL "hackbar" zu machen, wäre es schön, wenn ein Benutzer einfach die Getränke.aspx aus /Products/Beverages.aspx hacken und eine Auflistung der Produktkategorien anzeigen könnte. Auf den ersten Blick kann dies eine triviale Aufgabe sein – fügen Sie einfach eine Neuschreibungsregel hinzu, die /Products/ zu /ListCategories.aspx zugeordnet. Es gibt jedoch eine feine Subtilität – Sie müssen zuerst ein /Products/-Verzeichnis erstellen und eine leere Default.aspx-Datei im Verzeichnis "/Products/" hinzufügen.

Um zu verstehen, warum diese zusätzlichen Schritte ausgeführt werden müssen, erinnern Sie sich daran, dass sich das URL-Umschreibenmodul auf ASP.NET Ebene befindet. Wenn das ASP.NET-Modul niemals die Möglichkeit erhält, die Anforderung zu verarbeiten, gibt es keine Möglichkeit, das URL-Umschreibenmodul zu überprüfen. Denken Sie außerdem daran, dass IIS eingehende Anforderungen nur dann an das ASP.NET-Modul ausgibt, wenn die angeforderte Datei über eine entsprechende Erweiterung verfügt. Wenn also ein Benutzer /Products/besucht, wird in IIS keine Dateierweiterung angezeigt. Daher überprüft er das Verzeichnis, um festzustellen, ob eine Datei mit einem der Standarddateinamen vorhanden ist. (Default.aspx, Default.htm, Default.asp usw.. Diese Standarddateinamen werden auf der Registerkarte "Dokumente" des Dialogfelds "Webservereigenschaften" im Dialogfeld "IIS-Verwaltung" definiert.) Wenn das Verzeichnis "/Products/" nicht vorhanden ist, gibt IIS einen HTTP 404-Fehler zurück.

Daher müssen wir das Verzeichnis "/Products/" erstellen. Darüber hinaus müssen wir eine einzelne Datei in diesem Verzeichnis, Default.aspx, erstellen. Wenn ein Benutzer /Products/ besucht, überprüft IIS das Verzeichnis, sehen Sie, dass eine Datei namens Default.aspx vorhanden ist und dann die Verarbeitung an das ASP.NET-Modul übergeben wird. Unsere URL-Neuautorin erhält dann beim Neuschreiben der URL einen Riss.

Nachdem Sie die Datei "Directory" und "Default.aspx" erstellt haben, fahren Sie fort, und fügen Sie dem Rules-Element> die folgende Neuschreibungsregel< hinzu:

<RewriterRule>
   <LookFor>~/Products/Default\.aspx</LookFor>
   <SendTo>~/ListCategories.aspx</SendTo>
</RewriterRule>

Wenn ein Benutzer /Products/Products/Default.aspx besucht, wird in dieser Regel die Auflistung der Produktkategorien angezeigt, die in Abbildung 4 dargestellt sind.

ms972974.urlrewriting_fig04(en-us,MSDN.10).gif

Abbildung 4. Hinzufügen von "Hackability" zur URL

Behandeln von Postbacks

Wenn die URLs, die Sie neu schreiben, ein serverseitiges Webformular enthalten und Postbacks ausführen, wenn die Formularbeiträge zurückgepostet werden, wird die zugrunde liegende URL verwendet. Wenn der Benutzer seinen Browser /Products/Beverages.aspx eingibt, wird er weiterhin in der Adressleiste des Browsers /Products/Beverages.aspx angezeigt, aber er wird den Inhalt für ListProductsByCategory.aspx angezeigt? CategoryID=1. Wenn ListProductsByCategory.aspx einen Postback ausführt, wird der Benutzer wieder in ListProductsByCategory.aspx gepostet? CategoryID=1, nicht /Products/Beverages.aspx. Dadurch wird nichts unterbrochen, aber es kann aus der Perspektive des Benutzers verunsichert werden, um die URL plötzlich zu ändern, wenn sie auf eine Schaltfläche klicken.

Der Grund für dieses Verhalten besteht darin, dass das Aktionsattribute explizit auf den Wert des Dateipfads im Request-Objekt festgelegt wird, wenn das Webformular gerendert wird. Natürlich wurde die URL nach dem Rendern des Webformulars von "/Products/Beverages.aspx" in "ListProductsByCategory.aspx" neu geschrieben? CategoryID=1, d. h. das Request-Objekt meldet, dass der Benutzer ListProductsByCategory.aspx besucht? CategoryID=1. Dieses Problem kann behoben werden, indem das serverseitige Formular einfach kein Aktionsattribute rendert. (Browser werden standardmäßig postback verwendet, wenn das Formular kein Aktionsattribute enthält.)

Leider erlaubt das Webformular keine explizite Angabe eines Aktionsattributes oder ermöglicht es Ihnen, einige Eigenschaften festzulegen, um das Rendern des Aktionsattributes zu deaktivieren. Stattdessen müssen wir die System.Web.HtmlControls.HtmlForm-Klasse selbst erweitern, die RenderAttribute() -Methode außer Kraft setzen und explizit angeben, dass das Aktionsattribut nicht gerendert wird.

Dank der Macht der Vererbung können wir alle Funktionen der HtmlForm-Klasse gewinnen und müssen nur ein wenig Codezeilen hinzufügen, um das gewünschte Verhalten zu erzielen. Der vollständige Code für die benutzerdefinierte Klasse wird unten angezeigt:

namespace ActionlessForm {
  public class Form : System.Web.UI.HtmlControls.HtmlForm
  {
     protected override void RenderAttributes(HtmlTextWriter writer)
     {
        writer.WriteAttribute("name", this.Name);
        base.Attributes.Remove("name");

        writer.WriteAttribute("method", this.Method);
        base.Attributes.Remove("method");

        this.Attributes.Render(writer);

        base.Attributes.Remove("action");

        if (base.ID != null)
           writer.WriteAttribute("id", base.ClientID);
     }
  }
}

Der Code für die überschriebene RenderAttributes()-Methode enthält einfach den genauen Code aus der RenderAttributes()-Methode der HtmlForm-Klasse, aber ohne das Aktionsattribut festzulegen. (Ich habe den Reflektor von Lutz Roeder verwendet, um den Quellcode der HtmlForm-Klasse anzuzeigen.)

Nachdem Sie diese Klasse erstellt und kompiliert haben, um sie in einer ASP.NET Webanwendung zu verwenden, beginnen Sie, indem Sie sie dem Ordner "Verweise" der Webanwendung hinzufügen. Fügen Sie dann, um sie anstelle der HtmlForm-Klasse zu verwenden, einfach Folgendes oben auf Ihrer ASP.NET Webseite hinzu:

<%@ Register TagPrefix="skm" Namespace="ActionlessForm" 
   Assembly="ActionlessForm" %>

Ersetzen Sie dann, wo Sie dies haben <form runat="server">, durch:

<skm:Form id="Form1" method="post" runat="server">

und ersetzen Sie das schließende </form> Tag durch:

</skm:Form>

Sie können diese benutzerdefinierte Webformularklasse in Aktion in ListProductsByCategory.aspx sehen, die im Download dieses Artikels enthalten ist. Auch im Download enthalten ist ein Visual Studio .NET-Projekt für das aktionslose Webformular.

Hinweis Wenn die URL, in die Sie schreiben, kein Postback ausführt, muss diese benutzerdefinierte Web Form-Klasse nicht verwendet werden.

Erstellen wirklich "Hackable"-URLs

Die einfache URL-Neuschreibung im vorherigen Abschnitt zeigte, wie einfach das URL-Umschreibenmodul mit neuen Neuschreibungsregeln konfiguriert werden kann. Die wahre Kraft der Neuschreibungsregeln scheint jedoch, wenn reguläre Ausdrücke verwendet werden, wie wir in diesem Abschnitt sehen.

Blogs werden in diesen Tagen immer beliebter, und es scheint, dass jeder seinen eigenen Blog hat. Wenn Sie nicht mit Blogs vertraut sind, werden diese häufig aktualisierten persönlichen Seiten, die in der Regel als Onlinejournal dienen. Die meisten Blogger schreiben einfach über ihre täglichen Ereignisse, andere konzentrieren sich auf Blogging über ein bestimmtes Thema, z. B. Filmbewertungen, ein Sportteam oder eine Computertechnologie.

Je nach Autor werden Blogs überall von mehreren Tagen bis einmal pro Woche oder zwei aktualisiert. In der Regel zeigt die Blog-Homepage die neuesten 10 Einträge, aber praktisch alle Bloggingsoftware bietet ein Archiv, durch das Besucher ältere Beiträge lesen können. Blogs sind eine großartige Anwendung für "hackbare" URLs. Imagine beim Durchsuchen der Archive eines Blogs, den Sie sich unter der URL /2004/02/14.aspx gefunden haben. Würden Sie furchtbar überrascht sein, wenn Sie die Beiträge am 14. Februar 2004 gelesen haben? Darüber hinaus möchten Sie möglicherweise alle Beiträge für Februar 2004 anzeigen, in diesem Fall können Sie versuchen, die URL auf /2004/02//zu hacken. Um alle 2004 Beiträge anzuzeigen, können Sie versuchen, /2004/zu besuchen.

Bei der Verwaltung eines Blogs wäre es schön, diese URL-Ebene "Hackability" für Ihre Besucher bereitzustellen. Während viele Blogmodule diese Funktionalität bereitstellen, sehen wir uns an, wie sie mithilfe von URL-Neuschreibungen erreicht werden kann.

Zunächst benötigen wir eine einzelne ASP.NET Webseite, die Blogeinträge nach Tag, Monat oder Jahr anzeigt. Angenommen, wir haben eine solche Seite, ShowBlogContent.aspx, die Abfragezeichenfolgenparameter Jahr, Monat und Tag verwendet. Um die Beiträge für den 14. Februar 2004 anzuzeigen, könnten wir ShowBlogContent.aspx?year=2004&month=2&day=14 besuchen. Um alle Beiträge für Februar 2004 anzuzeigen, besuchen wir ShowBlogContent.aspx?year=2004&month=2. Schließlich navigieren wir zu ShowBlogContent.aspx?year=2004, um alle Beiträge für das Jahr 2004 anzuzeigen. (Der Code für ShowBlogContent.aspx finden Sie im Download dieses Artikels.)

Wenn ein Benutzer also /2004/02/14.aspx besucht, müssen wir die URL in ShowBlogContent.aspx?year=2004&month=2&day=14 neu schreiben. Alle drei Fälle – wenn die URL ein Jahr, einen Monat und einen Tag angibt; wenn die URL nur das Jahr und den Monat angibt; und wenn die URL nur das Ja angibt – kann mit drei Neuschreibregeln behandelt werden:

<RewriterConfig>
   <Rules>
      <!-- Rules for Blog Content Displayer -->
      <RewriterRule>
         <LookFor>~/(\d{4})/(\d{2})/(\d{2})\.aspx</LookFor>
         <SendTo>~/ShowBlogContent.aspx?year=$1&amp;month=$2&amp;day=$3</SendTo>
      </RewriterRule>
      <RewriterRule>
         <LookFor>~/(\d{4})/(\d{2})/Default\.aspx</LookFor>
         <SendTo><![CDATA[~/ShowBlogContent.aspx?year=$1&month=$2]]></SendTo>
      </RewriterRule>
      <RewriterRule>
         <LookFor>~/(\d{4})/Default\.aspx</LookFor>
         <SendTo>~/ShowBlogContent.aspx?year=$1</SendTo>
      </RewriterRule>
   </Rules>
</RewriterConfig>

Diese Neuschreibungsregeln veranschaulichen die Leistungsfähigkeit regulärer Ausdrücke. In der ersten Regel suchen wir nach einer URL mit dem Muster (\d)/(\d{4})/(\d{2})\d{2})\.aspx. In nur englischer Sprache entspricht dies einer Zeichenfolge mit vier Ziffern gefolgt von einem schrägen Schrägstrich gefolgt von zwei Ziffern gefolgt von einem Schrägstrich, gefolgt von zwei Ziffern gefolgt von zwei Ziffern gefolgt von .aspx. Die Klammer um jede Zifferngruppierung ist wichtig – es ermöglicht uns, auf die übereinstimmenden Zeichen in diesen Klammern in der entsprechenden <SendTo-Eigenschaft> zu verweisen. Insbesondere können wir auf die übereinstimmenden übergeordneten Gruppierungen verweisen, die $1, $2 und $3 für die erste, zweite und dritte Klammer gruppieren.

Hinweis Da die Web.config-Datei XML-formatiert ist, müssen Zeichen wie &<, und > im Textteil eines Elements escapet werden. Im SendTo-Element &>der< ersten Regel wird zu &amp;escapet. Im SendTo> der< zweiten Regel wird eine alternative Technik verwendet – mit einem <![ CDATA[...]]> element, der Inhalt innerhalb muss nicht escapet werden. Beide Ansätze sind akzeptabel und erreichen dasselbe Ende.

Abbildung 5, 6 und 7 zeigen die URL-Neuschreibung in Aktion an. Die Daten werden tatsächlich aus meinem Blog abgerufen, http://ScottOnWriting.NET. In Abbildung 5 werden die Beiträge für den 7. November 2003 angezeigt; in Abbildung 6 werden alle Beiträge für November 2003 angezeigt; Abbildung 7 zeigt alle Beiträge für 2003.

ms972974.urlrewriting_fig05(en-us,MSDN.10).gif

Abbildung 5. Beiträge für den 7. November 2003

ms972974.urlrewriting_fig06(en-us,MSDN.10).gif

Abbildung 6. Alle Beiträge für November 2003

ms972974.urlrewriting_fig07(en-us,MSDN.10).gif

Abbildung 7. Alle Beiträge für 2003

Hinweis Das URL-Neuschreibungsmodul erwartet ein reguläres Ausdrucksmuster in den <LookFor-Elementen> . Wenn Sie nicht mit regulären Ausdrücken vertraut sind, sollten Sie einen früheren Artikel von mir lesen, eine Einführung in reguläre Ausdrücke. Außerdem ist ein großartiger Ort, um Ihre Hände auf häufig verwendete reguläre Ausdrücke sowie ein Repository für die Freigabe Ihrer eigenen gestalteten regulären Ausdrücke zu erhalten, RegExLib.com.

Erstellen der erforderlichen Verzeichnisstruktur

Wenn eine Anforderung für /2004/03/19.aspx eingeht, notiert IIS die ASPX-Erweiterung und leitet die Anforderung an das ASP.NET-Modul weiter. Wenn die Anforderung durch die Pipeline des ASP.NET-Moduls wechselt, wird die URL in ShowBlogContent.aspx?year=2004 month=03&day=19 und der Besucher sehen diese Blogeinträge für den 19. März 2004&. Aber was geschieht, wenn der Benutzer zu /2004/03/? Es sei denn, es gibt ein Verzeichnis /2004/03//, IIS gibt einen 404-Fehler zurück. Darüber hinaus muss in diesem Verzeichnis eine Default.aspx-Seite vorhanden sein, damit die Anforderung an das ASP.NET-Modul übergeben wird.

Mit diesem Ansatz müssen Sie also ein Verzeichnis für jedes Jahr manuell erstellen, in dem Blogeinträge vorhanden sind, mit einer Default.aspx-Seite im Verzeichnis. Darüber hinaus müssen Sie in jedem Jahr manuell zwölf weitere Verzeichnisse erstellen – 01, 02, ..., 12 – jeweils mit einer Default.aspx-Datei. (Erinnern Sie sich daran, dass wir dasselbe tun mussten– fügen Sie ein /Products/Directory mit einer Default.aspx-Datei hinzu – in der vorherigen Demo, damit der Besuch von /Products/ ordnungsgemäß angezeigte ListCategories.aspx.)

Das Hinzufügen einer solchen Verzeichnisstruktur kann ein Schmerz sein. Eine Problemumgehung für dieses Problem besteht darin, dass alle eingehenden IIS-Anforderungen dem ASP.NET Modul zugeordnet sind. Auf diese Weise wird IIS auch dann, wenn sie die URL /2004/03// besuchen, die Anforderung an das ASP.NET-Modul übergeben, auch wenn kein /2004/03/Verzeichnis vorhanden ist. Die Verwendung dieses Ansatzes macht jedoch das ASP.NET Modul für die Behandlung aller Arten eingehender Anforderungen an den Webserver verantwortlich, einschließlich Bilder, CSS-Dateien, externe JavaScript-Dateien, Macromedia Flash Dateien usw.

Eine gründliche Diskussion über die Behandlung aller Dateitypen liegt weit über dem Umfang dieses Artikels hinaus. Ein Beispiel für eine ASP.NET Webanwendung, die diese Technik verwendet, schauen Sie sich jedoch an . Text, ein Open-Source-Blogmodul. . Text kann so konfiguriert werden, dass alle Anforderungen dem ASP.NET Modul zugeordnet sind. Es kann die Bereitstellung aller Dateitypen mithilfe eines benutzerdefinierten HTTP-Handlers behandeln, der weiß, wie typische statische Dateitypen (Bilder, CSS-Dateien usw.) bereitgestellt werden.

Zusammenfassung

In diesem Artikel haben wir untersucht, wie die URL-Neuschreibung auf ASP.NET-Ebene über die RewriteUrl() -Methode der HttpContext-Klasse ausgeführt wird. Wie wir gesehen haben, aktualisiert RewriteUrl() die bestimmte Anforderungseigenschaft von HttpContext, aktualisiert, welche Datei und welcher Pfad angefordert wird. Der Nettoeffekt besteht darin, dass sie aus Sicht des Benutzers eine bestimmte URL besuchen, aber tatsächlich wird eine andere URL auf der Webserverseite angefordert.

URLs können entweder in einem HTTP-Modul oder einem HTTP-Handler neu geschrieben werden. In diesem Artikel haben wir die Verwendung eines HTTP-Moduls zum Durchführen der Neuschreibung untersucht und die Folgen der Durchführung der Neuschreibung in verschiedenen Phasen in der Pipeline untersucht.

Natürlich kann die URL-Neuschreibung mit ASP.NET Ebene nur passieren, wenn die Anforderung erfolgreich von IIS an das ASP.NET-Modul übergeben wird. Dies tritt natürlich auf, wenn der Benutzer eine Seite mit einer ASPX-Erweiterung anfordert. Wenn Sie jedoch möchten, dass die Person eine URL eingeben soll, die möglicherweise nicht tatsächlich vorhanden ist, sondern stattdessen auf eine vorhandene ASP.NET Seite umschreiben möchte, müssen Sie entweder simulierte Verzeichnisse und Default.aspx-Seiten erstellen oder IIS so konfigurieren, dass alle eingehenden Anforderungen blind an das ASP.NET-Modul weitergeleitet werden.

ASP.NET: Tipps, Lernprogramme und Code

Microsoft ASP.NET Codierungsstrategien mit dem Microsoft ASP.NET Team

Wesentliche ASP.NET mit Beispielen in C #

Werke konsultiert

Die URL-Neuschreibung ist ein Thema, das sowohl für ASP.NET als auch für konkurrierende serverseitige Webtechnologien viel Aufmerksamkeit erhalten hat. Der Apache-Webserver stellt z. B. ein Modul für die URL-Neuschreibung bereit, die mod_rewrite aufgerufen wird. mod_rewrite ist ein robustes Neuschreibungsmodul, das Regeln basierend auf Bedingungen wie HTTP-Headern und Servervariablen sowie Neuschreibungsregeln bereitstellt, die reguläre Ausdrücke verwenden. Weitere Informationen zu mod_rewrite finden Sie im Leitfaden eines Benutzers zur URL-Neuschreibung mit dem Apache-Webserver.

Es gibt eine Reihe von Artikeln zur URL-Neuschreibung mit ASP.NET. Rewrite.NET – Ein URL-Neuschreibungsmodul für .NET untersucht das Erstellen eines URL-Neuschreibungsmoduls, das die regulären Ausdrucksregeln mod_rewrite nachahmt. Die URL-Neuschreibung mit ASP.NET bietet auch einen guten Überblick über ASP. DIE URL-Neuschreibungsfunktionen von NET. Ian Griffiths verfügt über einen Blogeintrag zu einigen der mit der URL-Umschreibung mit ASP.NET verknüpften URL-Neuschreibung, z. B. das in diesem Artikel erläuterte Postbackproblem. Sowohl Fabrice Marguerie (lesen Sie mehr) als auch Jason Salas (lesen Sie mehr) haben Blog-Ganzes über die Verwendung von URL-Neuschreibungen zur Steigerung der Suchmaschinenplatzierung.

 

Informationen zum Autor

Scott Mitchell, Autor von fünf Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit fünf Jahren mit Microsoft Web-Technologien zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Er kann über seinen Blog erreicht werden mitchell@4guysfromrolla.com , der unter http://ScottOnWriting.NET.

© Microsoft Corporation. Alle Rechte vorbehalten.