Artikel : <rewriter>
< umschreiben url = " ^/Benutzer/(d+)$ " to = " ~/User.aspx?id=$1 " Verarbeitung = „ Stopp “ />
< umschreiben url = " ^/User/(w+)$ " to = " ~/User.aspx?name=$1 " Verarbeitung = „ Stopp “ />
</ rewriter >
Wenn der Benutzer „/User/jeffz“ anfordert, lautet der auf der Seite angezeigte Code <form action="/User.aspx?name=jeffz" /> Dies liegt daran, dass beim Generieren des Codes Auf der Seite wird der aktuelle Wert von Request.Url.PathAndQuery verwendet, um die Aktion des Formularelements abzurufen. Dies führt dazu, dass „User.aspx?name=jeffz“ nach dem PostBack in der Adressleiste angezeigt wird und diese Adresse möglicherweise nicht die richtige Ressource anfordern kann (weil sie möglicherweise an anderer Stelle neu geschrieben wurde oder aufgrund von Beziehungen auf Verzeichnisebene). eine solche Ressource). Im vorherigen Artikel „ UpdatePanel und UrlRewrite “ habe ich gesagt, dass dieses Problem gelöst werden kann, indem am Ende der Seite eine Zeile JavaScript-Code hinzugefügt wird:
< script language = „javascript“ type = „text/javascript“>
document.getElementsByTagName( "form" )[0].action = window.location;
</script> Der Zweck
dieser Codezeile ist sehr offensichtlich. Ändern Sie die Aktion des Formulars in „window.location“ (d. h. den Pfad in der Adressleiste des Browsers), sodass die Zieladresse dies tut, wenn die Seite PostBack ausführt sei die Adresse vor dem URL-Rewrite. Dieser Ansatz kann dazu führen, dass das Programm normal läuft, aber er befriedigt mich nicht wirklich. Warum?
Weil es zu hässlich ist.
Weil wir die Adresse nach dem URL-Rewrite immer noch dem Client zugänglich machen. Solange der Benutzer einen HTTP-Sniffer (z. B. den berühmten Fiddler) installiert oder direkt auswählt, die Quelldatei im IE anzuzeigen, wird unsere Zieladresse dem Benutzer ohne jegliche Verheimlichung angezeigt. Wie können wir Benutzer über unsere Umschreibungsregeln informieren? Wir müssen dieses Problem lösen. Die Lösung ist sehr einfach und bereits sehr beliebt, nämlich die Verwendung des Control Adapters, um das Verhalten der Formulargenerierung zu ändern. Was mich jedoch seltsam macht, ist, dass alle Suchen nach diesem Steuerungsadapter im Internet VB.NET-Versionen sind, die hauptsächlich von Microsoft geförderte C#-Sprache jedoch nicht gefunden werden kann. Obwohl das Umschreiben nicht schwierig ist, solange Sie ein wenig die VB.NET-Syntax verstehen, ist es dennoch zusätzliche Arbeit. Deshalb werde ich jetzt den C#-Versionscode dieses Adapters veröffentlichen, damit Freunde ihn direkt verwenden können:
Namespace Sample.Web.UI.Adapters
{
öffentliche Klasse FormRewriterControlAdapter :
System.Web.UI.Adapters.ControlAdapter
{
protected override void Render( HtmlTextWriter -Writer)
{
base .Render( new RewriteFormHtmlTextWriter (Writer));
}
}
öffentliche Klasse RewriteFormHtmlTextWriter : HtmlTextWriter
{
public RewriteFormHtmlTextWriter ( HtmlTextWriter- Autor)
: base (Autor)
{
this .InnerWriter = write.InnerWriter;
}
public RewriteFormHtmlTextWriter ( TextWriter- Autor)
: base (Autor)
{
this .InnerWriter = Writer;
}
public override void WriteAttribute( string name, string value, bool fEncode)
{
if (name == "action" )
{
HttpContext context = HttpContext .Current;
if (context.Items[ "ActionAlreadyWritten" ] == null )
{
value = context.Request.RawUrl;
context.Items[ "ActionAlreadyWritten" ] = true ;
}
}
base .WriteAttribute(name, value, fEncode);
}
}
}
Um es einfach auszudrücken: Dieser Steueradapter hat tatsächlich auf den Moment gewartet, in dem das Attribut „action“ ausgegeben wird, und ändert den Wert in das RawUrl-Attribut des aktuellen Request-Objekts. Dieses Attribut wird bestimmt, wenn ASP.NET die Anfrage zum ersten Mal von IIS empfängt. Es ändert sich nicht mit der anschließenden Rewrite-Operation in BeginRequest. Daher müssen wir nur die RawUrl für die Form-Aktion ausgeben, um das Problem der PostBack-Adressänderung zu lösen.
Damit dieser Steuerungsadapter jedoch wirksam wird, müssen Sie auch eine Browserdatei im Webprojekt erstellen, z. B. „App_BrowsersForm.browser“, und den folgenden Code darin schreiben:
< browsers >
< Browser refID = " Standard " >
<controlAdapters>
< Adapter controlType = " System.Web.UI.HtmlControls.HtmlForm "
adapterType = " Sample.Web.UI.Adapters.FormRewriterControlAdapter " />
</ controlAdapters >
</ Browser >
</ browsers >
Zu diesem Zeitpunkt wurde das Problem der durch URL-Rewrite verursachten PostBack-Adressänderungen auf der ASP.NET-Ebene perfekt gelöst. Warten Sie, warum sollten wir die „ASP.NET-Ebene“ betonen? Das ist richtig, denn wenn Sie URL Rewrite auf IIS-Ebene durchführen, besteht dieses Problem weiterhin. Wenn Sie beispielsweise IIRF für URL Rewrite verwenden und den oben genannten Steueradapter aktivieren, werden Sie immer noch feststellen, dass sich die PostBack-Adresse auf der Seite von der vom Client angeforderten Adresse unterscheidet. Ist RawUrl auch „illoyal“ geworden? Dies liegt nicht an RawUrl, sondern wird durch den ASP.NET-Mechanismus bestimmt. Um dieses Problem zu erklären, werfen wir noch einmal einen Blick auf das Diagramm im ersten Artikel „ IIS und ASP.NET “:
Das Umschreiben der URL auf IIS-Ebene erfolgt vor Schritt 2 im obigen Bild. Da es umgeschrieben wird, übergibt der ISAPI-Selektor von IIS die Anforderung zur Verarbeitung an ASPNET ISAPI. Mit anderen Worten: Wenn IIS die Anforderung zur Verarbeitung an die ASP.NET-Engine übergibt, handelt es sich bei den Informationen, die ASP.NET von IIS erhält, bereits um die Adresse nach der URL-Umschreibung (z. B. /User.aspx?name=jeffz), also spielt es keine Rolle Unabhängig davon, wo ASP.NET die Anfrage verarbeitet, kann es die URL nicht kennen, als IIS die Anfrage empfangen hat.
Mit anderen Worten: Wir können wirklich nichts dagegen tun.
Die vier Worte „Es gibt wirklich keine Möglichkeit“ sind jedoch bedingt. Um es vollständig auszudrücken: „Sich auf ASP.NET selbst zu verlassen“ ist tatsächlich „Es gibt keine Möglichkeit“. Was aber, wenn uns IIS bei der URL-Umschreibung hilft? Als ausgereifte Open-Source-Komponente weiß IIRF natürlich, dass die ASP.NET-Engine und sogar alle ISAPI-Handler ihre Hilfe benötigen. Es kennt natürlich das Prinzip „Änderungen vornehmen, wenn Sie Änderungen vornehmen“ und hat daher gelernt, die Originaladresse zu speichern. Funktionen in der Servervariablen HTTP_X_REWRITE_URL. Allerdings wird IIRF dies nicht „bewusst“ tun (wie ermüdend), daher müssen wir es in der Konfigurationsdatei daran erinnern:
RewriteRule ^/User/(d+)$ /User.aspx?id=$1 [I, L , U ]
RewriteRule ^/User/(w+)$ /User.aspx?name=$1 [I, L, U]
Bitte beachten Sie, dass wir einen zusätzlichen Modifikator verwenden. Das Hinzufügen von U zur Modifier-Sammlung zeigt an, dass wir IIRF benötigen, um die ursprüngliche Adresse vor dem URL-Rewrite in der Servervariablen HTTP_X_REWRITE_URL zu speichern. Jetzt können wir diesen Wert in ASP.NET abrufen, also ändern wir die WriteAttribute-Methode im vorherigen Control Adapter-Code wie folgt:
public override void WriteAttribute( string name, string value, bool fEncode)
{
if (name == "action" )
{
HttpContext context = HttpContext .Current;
if (context.Items[ "ActionAlreadyWritten" ] == null )
{
value = context.Request.ServerVariables[ "HTTP_X_REWRITE_URL" ]
?? context.Request.RawUrl;
context.Items[ "ActionAlreadyWritten" ] = true ;
}
}
base .WriteAttribute(name, value, fEncode);
}
Jetzt wird der Wert der Aktion nicht einfach aus dem RawUrl-Attribut abgerufen, sondern es wird versucht, den Wert der Variablen HTTP_X_REWRITE_URL aus der ServerVariables-Sammlung abzurufen, da dort die Adresse der ursprünglichen von IIS empfangenen Anfrage gespeichert ist.
An dieser Stelle wurden die Hauptthemen zum URL-Rewrite behandelt. Im nächsten Artikel, der der letzte Artikel dieser Reihe ist, werden wir uns auf die Unterschiede in einigen Details konzentrieren, die durch die Verwendung verschiedener Ebenen des URL-Rewrite entstehen, und auf relevante Punkte Notiz.