Personalizar el control de errores para los controles UpdatePanel de ASP.NET
Actualización: noviembre 2007
Cuando se produce un error durante las actualizaciones parciales de página en controles UpdatePanel, según el comportamiento predeterminado se muestra un cuadro de mensaje de explorador con un mensaje de error. Este tutorial muestra cómo personalizar la forma en que se presenta el error al usuario y cómo personalizar el mensaje de error.
Requisitos previos
Para implementar los procedimientos en su propio entorno de desarrollo, necesitará:
Microsoft Visual Studio 2005 o Microsoft Visual Web Developer Express.
Un sitio web ASP.NET habilitado para AJAX.
Personalizar el control de errores en código de servidor
Para comenzar, personalizará el control de errores mediante código de servidor en la página.
Para personalizar el control de errores en código de servidor
Cree una nueva página y cambie a la vista Diseño.
En la ficha Extensiones AJAX del cuadro de herramientas, haga doble clic en el control ScriptManager y en el control UpdatePanel para agregarlos a la página.
Agregue los controles siguientes dentro del control UpdatePanel:
Dos controles TextBox.
Un control Label
Un control Button Establezca su propiedad Text en Calcular.
Texto dentro del control UpdatePanel.
Haga doble clic en el botón Calcular y agregue el código siguiente en su controlador de eventos:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try Dim a As Int32 a = Int32.Parse(TextBox1.Text) Dim b As Int32 b = Int32.Parse(TextBox2.Text) Dim res As Int32 = a / b Label1.Text = res.ToString() Catch ex As Exception If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then ex.Data("ExtraInfo") = " You can't divide " & _ TextBox1.Text & " by " & TextBox2.Text & "." End If Throw ex End Try End Sub
protected void Button1_Click(object sender, EventArgs e) { try { int a = Int32.Parse(TextBox1.Text); int b = Int32.Parse(TextBox2.Text); int res = a / b; Label1.Text = res.ToString(); } catch (Exception ex) { if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0) { ex.Data["ExtraInfo"] = " You can't divide " + TextBox1.Text + " by " + TextBox2.Text + "."; } throw ex; } }
El código contiene una instrucción try-catch. En el bloque try, el código realiza la división de los valores escritos en los cuadros de texto. Si se produce un error en la operación, el código del bloque catch agrega la información de la cadena adicional de ExtraInfo a la excepción y, a continuación, vuelve a generar la excepción sin administrarla.
Cambie a la vista Diseño y seleccione el control ScriptManager.
En la barra de herramientas de la ventana Propiedades, haga clic en el botón Eventos y, a continuación, haga doble clic en el cuadro AsyncPostBackError para crear un controlador para este evento.
Agregue el código siguiente al controlador de eventos AsyncPostBackError:
Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) If (e.Exception.Data("ExtraInfo") <> Nothing) Then ScriptManager1.AsyncPostBackErrorMessage = _ e.Exception.Message & _ e.Exception.Data("ExtraInfo").ToString() Else ScriptManager1.AsyncPostBackErrorMessage = _ "An unspecified error occurred." End If End Sub
protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { if (e.Exception.Data["ExtraInfo"] != null) { ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message + e.Exception.Data["ExtraInfo"].ToString(); } else { ScriptManager1.AsyncPostBackErrorMessage = "An unspecified error occurred."; } }
El código comprueba si se define el elemento de datos ExtraInfo para la excepción. Si es así, la propiedad AsyncPostBackErrorMessage se establece en el valor de la cadena. De lo contrario, se crea un mensaje de error predeterminado.
Guarde los cambios y presione CTRL+F5 para ver la página en un explorador.
Agregue un número mayor que cero en cada cuadro de texto y, a continuación, haga clic en el botón Calcular para mostrar una devolución de datos correcta.
Cambie el valor del segundo cuadro de texto a 0 y, a continuación, haga clic en el botón Calcular para crear una condición de error.
El explorador muestra un cuadro de mensaje que contiene el mensaje establecido en el código de servidor.
Nota: El estilo del cuadro de mensaje depende del explorador que se use, pero el mensaje será el mismo en todos los exploradores.
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try Dim a As Int32 a = Int32.Parse(TextBox1.Text) Dim b As Int32 b = Int32.Parse(TextBox2.Text) Dim res As Int32 = a / b Label1.Text = res.ToString() Catch ex As Exception If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then ex.Data("ExtraInfo") = " You can't divide " & _ TextBox1.Text & " by " & TextBox2.Text & "." End If Throw ex End Try End Sub Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) If (e.Exception.Data("ExtraInfo") <> Nothing) Then ScriptManager1.AsyncPostBackErrorMessage = _ e.Exception.Message & _ e.Exception.Data("ExtraInfo").ToString() Else ScriptManager1.AsyncPostBackErrorMessage = _ "An unspecified error occurred." End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Partial-Page Update Error Handling Example</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { try { int a = Int32.Parse(TextBox1.Text); int b = Int32.Parse(TextBox2.Text); int res = a / b; Label1.Text = res.ToString(); } catch (Exception ex) { if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0) { ex.Data["ExtraInfo"] = " You can't divide " + TextBox1.Text + " by " + TextBox2.Text + "."; } throw ex; } } protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { if (e.Exception.Data["ExtraInfo"] != null) { ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message + e.Exception.Data["ExtraInfo"].ToString(); } else { ScriptManager1.AsyncPostBackErrorMessage = "An unspecified error occurred."; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Partial-Page Update Error Handling Example</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
Usar script de cliente para personalizar el control de errores
El procedimiento anterior mostraba cómo personalizar los errores durante la representación parcial de páginas mediante el establecimiento de las propiedades del control ScriptManager. El procedimiento siguiente genera la personalización con la clase de cliente PageRequestManager para mostrar el mensaje de error en un elemento <div> en lugar de mostrarlo en un cuadro de mensaje del explorador.
Para personalizar el control de errores en script de cliente
En la página que creó anteriormente, cambie a la vista Código fuente.
Agregue el marcado siguiente a la página:
<div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div>
<div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div>
El marcado incluye elementos que puede usar para mostrar los errores de la representación parcial de la página. Define un elemento <div> denominado AlertDiv que contiene otros dos elementos <div>. Uno de los elementos <div> anidados contiene un control <input> que permitirá a los usuarios ocultar el elemento <div>.
Agregue el marcado de estilo siguiente en el elemento <head>:
<style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style>
<style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style>
Los estilos consiguen que la información de error destaque visualmente del resto del contenido de la página.
Cambie a la vista Diseño y compruebe que su página es similar a la siguiente:
En la lista desplegable en la parte superior de la ventana Propiedades, seleccione el elemento DOCUMENT (que representa al elemento <body> en la página) y establezca su propiedad Id en bodytag.
Cambie a la vista de código fuente.
Agregue el bloque <script> siguiente en cualquier parte después del elemento <asp:ScriptManager>.
<script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script>
<script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script>
Este script realiza lo siguiente:
Define un controlador para el evento endRequest de la clase PageRequestManager. En el controlador, el código muestra el elemento AlertDiv <div> si existe una condición de error.
Define la función ToggleAlertDiv, que oculta o muestra el elemento AlertDiv y cambia el color de la página basándose en una condición de error.
Define la función ClearErrorState, que oculta la interfaz de usuario del mensaje de error.
Guarde los cambios y presione CTRL+F5 para ver la página en un explorador.
Agregue un número mayor que cero en cada cuadro de texto y, a continuación, haga clic en el botón Calcular para mostrar una devolución de datos correcta.
Cambie el valor del segundo cuadro de texto a 0 y, a continuación, haga clic en el botón Calcular para mostrar una condición de error.
Se muestra el elemento AlertDiv personalizado en lugar del cuadro de mensaje del explorador. En la ilustración siguiente se muestra un ejemplo de la condición de error.
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try Dim a As Int32 a = Int32.Parse(TextBox1.Text) Dim b As Int32 b = Int32.Parse(TextBox2.Text) Dim res As Int32 = a / b Label1.Text = res.ToString() Catch ex As Exception If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then ex.Data("ExtraInfo") = " You can't divide " & _ TextBox1.Text & " by " & TextBox2.Text & "." End If Throw ex End Try End Sub Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) If (e.Exception.Data("ExtraInfo") <> Nothing) Then ScriptManager1.AsyncPostBackErrorMessage = _ e.Exception.Message & _ e.Exception.Data("ExtraInfo").ToString() Else ScriptManager1.AsyncPostBackErrorMessage = _ "An unspecified error occurred." End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>UpdatePanel Error Handling Example</title> <style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style> </head> <body id="bodytag"> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> <div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { try { int a = Int32.Parse(TextBox1.Text); int b = Int32.Parse(TextBox2.Text); int res = a / b; Label1.Text = res.ToString(); } catch (Exception ex) { if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0) { ex.Data["ExtraInfo"] = " You can't divide " + TextBox1.Text + " by " + TextBox2.Text + "."; } throw ex; } } protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { if (e.Exception.Data["ExtraInfo"] != null) { ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message + e.Exception.Data["ExtraInfo"].ToString(); } else { ScriptManager1.AsyncPostBackErrorMessage = "An unspecified error occurred."; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>UpdatePanel Error Handling Example</title> <style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style> </head> <body id="bodytag"> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> <div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div> </form> </body> </html>
Revisión
En este tutorial se han mostrado métodos para extender el control de errores durante la representación parcial de páginas. En código de servidor puede personalizar el control de errores si establece la propiedad AsyncPostBackErrorMessage y administra el evento AsyncPostBackError del control ScriptManager. En código de cliente puede personalizar el control de errores si administra el evento endRequest de la clase PageRequestManager.
Vea también
Conceptos
Trabajar con eventos de PageRequestManager