ejemplo : <rewriter>
< reescribir URL = " ^/Usuario/(d+)$ " a = " ~/Usuario.aspx?id=$1 " procesamiento = " detener " />
< reescribir URL = " ^/Usuario/(w+)$ " a = " ~/Usuario.aspx?nombre=$1 " procesamiento = " detener " />
</ rewriter >
Cuando el usuario solicita "/User/jeffz", el código que aparece en la página será <form action="/User.aspx?name=jeffz" />. Esto se debe a que cuando se genera el código, la página El valor actual de Request.Url.PathAndQuery se utilizará para obtener la acción del elemento del formulario. Esto hace que "User.aspx?name=jeffz" aparezca en la barra de direcciones una vez que se realiza la devolución, y es posible que esta dirección no pueda solicitar el recurso correcto (porque puede estar reescrito en otro lugar o debido a relaciones a nivel de directorio). dicho recurso). En el artículo anterior " UpdatePanel y UrlRewrite ", dije que este problema se puede resolver agregando una línea de código JavaScript al final de la página:
< script language ="javascript" type ="text/javascript">
document.getElementsByTagName( "formulario" )[0].action = ventana.ubicación;
</script> El propósito
de esta línea de código es muy obvio. Cambie la acción del formulario a window.location (es decir, la ruta en la barra de direcciones del navegador), de modo que cuando la página realice PostBack, la dirección de destino. sea la dirección antes de la reescritura de URL. Este método puede hacer que el programa se ejecute normalmente, pero realmente no me satisface. ¿Por qué?
Porque es demasiado feo.
Porque todavía exponemos la dirección después de la reescritura de URL al cliente. Siempre que el usuario instale un rastreador HTTP (como el famoso Fiddler) o seleccione directamente ver el archivo fuente en IE, nuestra dirección de destino se mostrará frente al usuario sin ningún tipo de ocultación. ¿Cómo podemos informar a los usuarios nuestras reglas de reescritura? Debemos resolver este problema. La solución es muy simple y ya muy popular, y consiste en utilizar Control Adapter para cambiar el comportamiento de la generación de formularios. Pero lo que me hace sentir extraño es que todas las búsquedas de este Adaptador de control en Internet son versiones VB.NET, pero no se puede encontrar el lenguaje C# promovido principalmente por Microsoft. Aunque no es difícil reescribirlo siempre que comprenda un poco la sintaxis de VB.NET, después de todo sigue siendo un trabajo extra. Así que publicaré el código de la versión C# de este Adaptador ahora para que mis amigos puedan usarlo directamente:
espacio de nombres Sample.Web.UI.Adapters
{
clase pública FormRewriterControlAdapter :
System.Web.UI.Adapters.ControlAdapter
{
Anulación protegida Renderizado vacío (escritor HtmlTextWriter )
{
base .Render ( nuevo RewriteFormHtmlTextWriter (escritor));
}
}
clase pública RewriteFormHtmlTextWriter : HtmlTextWriter
{
público RewriteFormHtmlTextWriter (escritor HtmlTextWriter )
: base (escritor)
{
este .InnerWriter = escritor.InnerWriter;
}
público RewriteFormHtmlTextWriter (escritor TextWriter )
: base (escritor)
{
este .InnerWriter = escritor;
}
anulación pública void WriteAttribute (nombre de cadena , valor de cadena , bool fEncode)
{
si (nombre == "acción" )
{
Contexto HttpContext = HttpContext .Actual;
if (context.Items[ "AcciónAlreadyWritten" ] == nulo )
{
valor = contexto.Request.RawUrl;
contexto.Items[ "AcciónAlreadyWritten" ] = verdadero ;
}
}
base .WriteAttribute(nombre, valor, fEncode);
}
}
}
En pocas palabras, este Adaptador de control ha estado esperando el momento en que se genera el atributo "acción" y cambia el valor al atributo RawUrl del objeto Solicitud actual. Este atributo se determina cuando ASP.NET recibe por primera vez la solicitud de IIS. No cambiará con la operación de reescritura posterior en BeginRequest. Por lo tanto, solo necesitamos generar RawUrl para la acción Formulario para resolver el problema de cambio de dirección de devolución.
Sin embargo, para que este Adaptador de control surta efecto, también debe crear un archivo de navegador en el proyecto web, como "App_BrowsersForm.browser", y escribir el siguiente código en él:
< navegadores >
< navegador refID = " Predeterminado " >
<adaptadores de control>
< adaptador controlType = " System.Web.UI.HtmlControls.HtmlForm "
AdapterType = " Sample.Web.UI.Adapters.FormRewriterControlAdapter " />
</ adaptadores de control >
</ navegador >
</ browsers >
En este punto, el problema de los cambios de dirección PostBack causados por la reescritura de URL en el nivel ASP.NET se ha resuelto perfectamente; espere, ¿por qué deberíamos enfatizar el "nivel ASP.NET"? Así es, porque si realiza la reescritura de URL en el nivel de IIS, este problema aún existe. Por ejemplo, si usa IIRF para reescritura de URL y habilita el Adaptador de control anterior, aún encontrará que la dirección de devolución de datos en la página es diferente de la dirección solicitada por el cliente. ¿RawUrl también se ha vuelto "desleal"? Esto no se debe a RawUrl, sino que está determinado por el mecanismo ASP.NET. Para explicar este problema, echemos un vistazo nuevamente al diagrama del primer artículo " IIS y ASP.NET ":
La reescritura de URL a nivel de IIS ocurre antes del paso 2 en la imagen de arriba. Debido a que está reescrita, el selector ISAPI de IIS entregará la solicitud a ASPNET ISAPI para su procesamiento. En otras palabras, cuando IIS entrega la solicitud al motor ASP.NET para su procesamiento, la información que ASP.NET obtiene de IIS ya es la dirección después de la reescritura de URL (por ejemplo, /User.aspx?name=jeffz), por lo que no importa. No importa dónde ASP.NET procese la solicitud, no puede conocer la URL cuando IIS recibió la solicitud.
En otras palabras, realmente no hay nada que podamos hacer al respecto.
Sin embargo, las cuatro palabras "realmente no hay manera" son condicionales. Para decirlo completamente, debería ser: "confiar en el propio ASP.NET" es de hecho "no hay manera". Pero ¿qué pasa si IIS nos ayuda a la hora de realizar la reescritura de URL? Como componente maduro de código abierto, IIRF naturalmente sabe que el motor ASP.NET e incluso todos los controladores ISAPI necesitan su ayuda. Naturalmente, conoce el principio de "hacer cambios cuando se realizan cambios", por lo que ha aprendido a almacenar la dirección original. Capacidades en la variable del servidor HTTP_X_REWRITE_URL. Sin embargo, IIRF no hará esto "conscientemente" (qué agotador), por lo que debemos recordarlo en el archivo de configuración:
RewriteRule ^/User/(d+)$ /User.aspx?id=$1 [I, L, U ]
RewriteRule ^/User/(w+)$ /User.aspx?name=$1 [I, L, U]
Tenga en cuenta que utilizamos un modificador adicional. Agregar U a la colección de modificadores indica que necesitamos IIRF para almacenar la dirección original antes de la reescritura de URL en la variable del servidor HTTP_X_REWRITE_URL. Ahora podemos obtener este valor en ASP.NET, por lo que modificamos el método WriteAttribute en el código anterior del Adaptador de control de la siguiente manera:
public override void WriteAttribute( nombre de cadena , valor de cadena , bool fEncode)
{
si (nombre == "acción" )
{
Contexto HttpContext = HttpContext .Actual;
if (context.Items[ "AcciónAlreadyWritten" ] == nulo )
{
valor = contexto.Request.ServerVariables[ "HTTP_X_REWRITE_URL" ]
?? contexto.Solicitud.RawUrl;
contexto.Items[ "AcciónAlreadyWritten" ] = verdadero ;
}
}
base .WriteAttribute(nombre, valor, fEncode);
}
Ahora el valor de la acción no se obtiene simplemente del atributo RawUrl, sino que intenta obtener el valor de la variable HTTP_X_REWRITE_URL de la colección ServerVariables, porque allí se almacena la dirección de la solicitud original recibida por IIS.
Hasta este punto, se han cubierto los temas principales sobre la reescritura de URL. En el próximo artículo, que es el último de esta serie, nos centraremos en las diferencias en algunos detalles causadas por el uso de diferentes niveles de reescritura de URL y los puntos relevantes de. nota.