Recibí un correo electrónico hoy y me preguntaron por qué UpdatePanel causaría problemas si se combinara con UrlRewrite. Al principio no lo tomé en serio, porque también había usado UpdatePanel en UrlRewrite antes y no hubo ningún problema. Sin embargo, después de recibir el código empaquetado de la otra parte, descubrí que el problema había vuelto a ocurrir. Si accedía a la página de destino directamente, no habría ningún problema. Porque yo estaba en la empresa en ese momento y no estudié detenidamente la causa del error. De camino a casa, simulé mentalmente el proceso de implementación de UpdatePanel una y otra vez, pero no noté nada malo. Al final, no pude evitarlo. Abrí mi computadora portátil mientras estaba sentado en el autobús y busqué cuidadosamente el problema. El autobús temblaba mucho, pero afortunadamente finalmente encontré el problema antes de vomitar. Mi forma de pensar en ese momento todavía estaba equivocada.
Reproduciendo el problema:
Ahora reproduciré el problema. El UrlRewriteModule de NBear se usó en el código original. En aras de la simplicidad, utilicé el método UrlRewrite más común para obtener el mismo efecto, tratando de evitar que algunos amigos (incluyéndome a mí) que no están familiarizados con NBear obstaculicen la comprensión del artículo. contenido.
Primero, cree un nuevo sitio web compatible con ASP.NET AJAX. Cree un archivo ~/SubFolder/Target.aspx con el siguiente contenido:
~/SubFolder/Target.aspx
<html xmlns=" http://www.w3.org/1999/xhtml " >
<head runat="servidor">
<título>Página de destino</título>
</cabeza>
<cuerpo>
<formulario id="form1" runat="servidor">
<asp:ScriptManager ID="ScriptManager1" runat="servidor">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="servidor">
<Plantilla de contenido>
<%= DateTime.Now.ToString() %>
<asp:ID de botón="Botón1" runat="servidor" Texto="Actualizar" />
</ContentTemplate>
</asp:Panel de actualización>
</formulario>
</cuerpo>
</html>
Luego cree un Global.asax, proporcione el método Application_BeginRequest e implemente Url Rewrite en él, de la siguiente manera:
Método Application_BeginRequest en Global.asax
void Application_BeginRequest (remitente del objeto, EventArgs e)
{
Contexto HttpContext = (remitente como HttpApplication).Context;
si (context.Request.Path.Contains("Fuente.aspx"))
{
contexto.RewritePath("SubFolder/Target.aspx", falso);
}
}
De esta manera, cuando accedamos al archivo ~/Source.aspx, se reescribirá en ~/SubFolder/Target.aspx, abriremos la página y todo será normal:
Después de hacer clic en el botón Actualizar, la hora se actualiza. Luego, cuando volvimos a hacer clic en el botón, se produjo el error: "Sys.WebForms.PageRequestManagerServerErrorException: se produjo un error desconocido al procesar la solicitud en el servidor. El código de estado devuelto por el servidor fue: 12031".
Análisis del problema:
el motivo de este problema es que Url Rewrite actualiza la dirección enviada por el formulario y UpdatePanel refleja el cambio en la dirección de la página.
Cuando abrimos la página por primera vez, podemos ver que la acción del elemento <form /> en el archivo fuente de la página ya no es el Source.aspx al que accedemos, sino el archivo de destino después de Url Rewrite:
la acción del elemento de formulario es la página de destino
...
<nombre del formulario="form1" método="post" acción="SubFolder/Target.aspx" id="form1">
...
</formulario>
...
Afortunadamente, utilizamos representación parcial. Siempre que el "destino" sea correcto, UpdatePanel aún puede enviar y recibir datos correctamente y luego actualizar la página. Por lo tanto, después de hacer clic en el botón Actualizar, la página se actualiza correctamente. Sin embargo, la acción de nuestro elemento de formulario también ha cambiado, lo que se puede ver de un vistazo usando Web Development Helper y IE Dev Toolbar:
Dado que accedemos directamente a ~/SubFolder/Target.aspx al realizar una devolución de datos asincrónica, el valor de acción del objeto de formulario generado es Target.aspx. Como resultado, UpdatePanel modificó diligentemente la acción del elemento de formulario del cliente. Esto nos permitirá acceder a una página inexistente cuando la enviemos nuevamente, y los errores son inevitables.
Resuelva el problema:
ahora que ha descubierto el problema, naturalmente podrá resolverlo fácilmente. Solo necesitamos responder al evento de carga de Sys.Application. Se activará cuando la página se cargue por primera vez y después de cada representación parcial. En este momento, podemos modificar el atributo de acción del elemento de formulario en la página. , de la siguiente manera:
Evento de carga de Sys.Application correspondiente
Sys.Application.add_load(función()
{
formulario var = Sys.WebForms.PageRequestManager.getInstance()._form;
form._initialAction = form.action = ventana.ubicación.href;
});
En cuanto a por qué el elemento de formulario en la página debe obtenerse de esta manera, qué es _initialAction y por qué debe configurarse, implica la implementación de UpdatePanel, por lo que no lo explicaré aquí. Siempre que se coloque un fragmento de código tan pequeño en la página, este problema se resuelve.
Pregunta detallada:
la razón de este problema es en realidad que después de Url Rewrite, la acción del elemento de formulario no es la dirección solicitada por el cliente, sino la dirección de destino de Url Rewrite. Si no utilizamos representación parcial, sino que utilizamos el PostBack más tradicional, aunque la función de la página no se dañará, después de PostBack, el usuario encontrará que el contenido de la barra de direcciones ha cambiado y se convierte directamente en la dirección de destino. Este no es el resultado que queremos ver. Ahora que lo hemos reescrito, reescribámoslo hasta el final. Por supuesto, todavía podemos usar el método mencionado anteriormente y usar JavaScript para modificar la acción del elemento del formulario, pero este método no es lo suficientemente "hermoso" y el usuario también puede ver la dirección de destino de nuestra URL Rewrite desde la fuente HTML. archivo, no?
Sería fantástico si pudiéramos configurar la acción del formulario en el lado del servidor, pero desafortunadamente la clase System.Web.UI.HtmlControls.HtmlForm no nos permite hacer esto. Pero, afortunadamente, usamos ASP.NET y utilizamos el modelo de programación orientada a objetos. Entonces "heredamos" System.Web.UI.HtmlControls.HtmlForm e implementamos nuestro propio control de formulario:
heredamos la clase HtmlForm para implementar nuestro propio From
espacio de nombres ActionlessForm {
Formulario de clase pública: System.Web.UI.HtmlControls.HtmlForm
{
anulación protegida void RenderAttributes (escritor HtmlTextWriter)
{
escritor.WriteAttribute("nombre", este.Nombre);
base.Attributes.Remove("nombre");
escritor.WriteAttribute("método", this.Method);
base.Attributes.Remove("método");
this.Attributes.Render(escritor);
base.Attributes.Remove("acción");
si (base.ID! = nulo)
escritor.WriteAttribute("id", base.ClientID);
}
}
}
Entonces podemos usarlo en la página. Por supuesto, antes de eso, debemos registrarlo en la página (o Web.config):
use nuestro propio formulario implementado
<%@ Registrar TagPrefix="skm" Namespace="ActionlessForm"
Asamblea="Forma sin acción" %>
...
<skm:Form id="Form1" método="post" runat="servidor">
...
</skm:Formulario>
...
En este punto, ya no necesitamos escribir un JavaScript "inteligente" en la página. Se resuelve el problema de acción del elemento de formulario después de la reescritura de URL.
("Preguntas detalladas" se refieren a parte del artículo anterior en MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp )
http://www.cnblogs.com/JeffreyZhao/archive/2006/12/27/updatepanel_with_url_rewrite.html