Controlar e iniciar excepciones en servicios Web XML
Las excepciones iniciadas por un método de servicio Web XML creado mediante ASP.NET se envían de vuelta al cliente en forma de un error de SOAP. Un error de SOAP es un elemento XML <Fault> contenido en un mensaje SOAP que especifica cuándo se produjo un error. Al pasar un error de SOAP, ASP.NET sigue el método designado en la especificación SOAP para la propagación de errores a un cliente. El elemento XML <Fault> de SOAP contiene información como la cadena y el origen de la excepción. Para obtener más información acerca de los errores de SOAP, visite el sitio Web de W3C (World Wide Web Consortium), http://www.w3.org/TR/SOAP.
Afortunadamente, los clientes y los servicios Web XML creados mediante ASP.NET no llenan ni analizan directamente el elemento XML <Fault>, sino que utilizan el modelo de diseño común en .NET Framework para iniciar y detectar excepciones. Un servicio Web XML puede iniciar una excepción específica del problema, como ArgumentOutOfRangeException, o una excepción SoapException. En ambos casos, ASP.NET serializa la excepción en un mensaje SOAP válido al colocar la excepción en un elemento de error de SOAP. Cuando se deserializa el mensaje SOAP en un cliente de ASP.NET, el error de SOAP se convierte en una excepción SoapException y los datos de la excepción se colocan en la propiedad Message. Por lo tanto, un cliente puede configurar un bloque Try/Catch para detectar una excepción SoapException.
Una aplicación Web puede estar compuesta por varios servicios Web XML, pero no se puede utilizar el evento Application_Error del archivo Global.asax para el control global de las excepciones. El controlador HttpHandler para los servicios Web XML consume cualquier excepción que se produzca durante la ejecución de un servicio Web XML y la convierte en un error de SOAP antes de que se llame al evento Application_Error. Cree una extensión SOAP para procesar excepciones de servicio Web XML en un controlador de excepciones global. Una extensión SOAP puede comprobar si existe una excepción en el método ProcessMessage. En el método ProcessMessage, compruebe la propiedad Exception del mensaje SoapMessage que se pasa cuando la propiedad Stage se establece en AfterSerialize. Para obtener más información acerca de las extensiones SOAP, vea Alterar el mensaje SOAP mediante extensiones SOAP.
Iniciar excepciones desde un servicio Web XML creado mediante ASP.NET
La propagación de errores a un cliente se realiza mediante el inicio de excepciones. En un servicio Web XML, hay cuatro formas de llevarlo a cabo:
- Iniciar una excepción SoapException.
- Iniciar una excepción SoapHeaderException.
- Iniciar una excepción específica del problema.
- Permitir que ASP.NET inicie la excepción.
En la tabla siguiente se describen las excepciones que un servicio Web XML puede iniciar de forma explícita y cómo se recibe cada excepción en un cliente de ASP.NET.
Tipo de excepción iniciada | Lo que puede hacer un servicio Web XML |
---|---|
Excepción distinta de SoapException y SoapHeaderException | Un método de servicio Web XML detecta un caso de excepción e inicia la excepción específica, como ArgumentOutOfRangeException, para el cliente. Un cliente de ASP.NET recibe una excepción SoapException con los datos serializados en texto en la propiedad Message. |
SoapException | Un método de servicio Web XML detecta un caso de excepción e inicia una excepción SoapException. Además, proporciona detalles adicionales relativos al problema. Para proporcionar la información adicional, el método de servicio Web XML llena la propiedad Detail. Un cliente de ASP.NET recibe la excepción SoapException con información adicional. |
SoapHeaderException | Un método de servicio Web XML detecta un caso de excepción al procesar un encabezado SOAP. De acuerdo con la especificación de SOAP, el método de servicio Web XML debe iniciar una excepción SoapHeaderException para el cliente. Un cliente de ASP.NET recibe la excepción SoapHeaderException. |
Para iniciar una excepción desde un servicio Web XML
Inicie la excepción específica del problema, como SoapException, o la excepción SoapHeaderException, según se describe en la tabla anterior.
En el ejemplo de código siguiente se inicia una excepción SoapException y se establece la propiedad Detail para proporcionar detalles adicionales acerca de la excepción.
<%@ WebService Language="VB" class="ThrowSoapException"%> Imports System Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Xml.Serialization Imports System.Xml Public Class ThrowSoapException Inherits WebService ' This XML Web service method throws a SOAP client fault code. <WebMethod()> _ Public Sub myThrow() ' Build the detail element of the SOAP fault. Dim doc As New System.Xml.XmlDocument() Dim node As System.Xml.XmlNode = _ doc.CreateNode(XmlNodeType.Element, _ SoapException.DetailElementName.Name, _ SoapException.DetailElementName.Namespace) ' Build specific details for the SoapException. ' Add first child of detail XML element. Dim details As System.Xml.XmlNode = _ doc.CreateNode(XmlNodeType.Element, _ "mySpecialInfo1", "http://tempuri.org/") ' Add second child of detail XML element with an attribute. Dim details2 As System.Xml.XmlNode = _ doc.CreateNode(XmlNodeType.Element, _ "mySpecialInfo2", "http://tempuri.org/") Dim attr As XmlAttribute = doc.CreateAttribute("t", _ "attrName", "http://tempuri.org/") attr.Value = "attrValue" details2.Attributes.Append(attr) ' Append the two child elements to the detail node. node.AppendChild(details) node.AppendChild(details2) 'Throw the exception. Dim se As New SoapException("Fault occurred", _ SoapException.ClientFaultCode, _ Context.Request.Url.AbsoluteUri, node) Throw se Return End Sub End Class [C#] <%@ WebService Language="C#" class="ThrowSoapException"%> using System; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; using System.Xml; public class ThrowSoapException : WebService { // This XML Web service method throws a SOAP client fault code. [WebMethod] public void myThrow(){ // Build the detail element of the SOAP fault. System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); System.Xml.XmlNode node = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace); // Build specific details for the SoapException. // Add first child of detail XML element. System.Xml.XmlNode details = doc.CreateNode(XmlNodeType.Element, "mySpecialInfo1", "http://tempuri.org/"); System.Xml.XmlNode detailsChild = doc.CreateNode(XmlNodeType.Element, "childOfSpecialInfo", "http://tempuri.org/"); details.AppendChild(detailsChild); // Add second child of detail XML element with an attribute. System.Xml.XmlNode details2 = doc.CreateNode(XmlNodeType.Element, "mySpecialInfo2", "http://tempuri.org/"); XmlAttribute attr = doc.CreateAttribute("t", "attrName", "http://tempuri.org/"); attr.Value = "attrValue"; details2.Attributes.Append(attr); // Append the two child elements to the detail node. node.AppendChild(details); node.AppendChild(details2); //Throw the exception SoapException se = new SoapException("Fault occurred", SoapException.ClientFaultCode, Context.Request.Url.AbsoluteUri , node); throw se; return; } }
Para detectar una excepción iniciada por un método de servicio Web XML
En un bloque Try/Catch, detecte la excepción SoapException (todas las excepciones iniciadas por un método de servicio Web XML se inician como excepciones SoapException).
En el ejemplo de código siguiente de un cliente que llama a un método de servicio Web XML, se detecta la excepción iniciada por dicho método. Después, el cliente llena una tabla HTML con las propiedades de la excepción SoapException detectada.
<%@ Import Namespace="System.Web.Services.Protocols" %> <%@ Import Namespace="System.Xml" %> <%@ Page Language="vb" %> <html> <head> <script runat=server language=vb> Sub Page_Load(o As Object, e As EventArgs) ' Create a new instance of the XML Web service class. Dim ThrowsSoapException As ThrowSoapException = New _ ThrowSoapException() Try ThrowsSoapException.myThrow() Catch myerr As SoapException ' Populate the table with the exception details. ErrorTable.Rows.Add(BuildNewRow("Fault Code Namespace", _ myerr.Code.Namespace)) ErrorTable.Rows.Add(BuildNewRow("Fault Code Name", _ myerr.Code.Name)) ErrorTable.Rows.Add(BuildNewRow( _ "SOAP Actor that threw Exception", myerr.Actor)) ErrorTable.Rows.Add(BuildNewRow("Error Message", _ myerr.Message)) ErrorTable.Rows.Add(BuildNewRow("Detail", _ HttpUtility.HtmlEncode(myerr.Detail.OuterXml) )) Return End Try End Sub 'Page_Load Function BuildNewRow(Cell1Text As String, Cell2Text As String) _ As HtmlTableRow Dim row As New HtmlTableRow() Dim cell1 As New HtmlTableCell() Dim cell2 As New HtmlTableCell() 'Set the contents of the two cells. cell1.Controls.Add(New LiteralControl(Cell1Text)) 'Add the cells to the row. row.Cells.Add(cell1) cell2.Controls.Add(New LiteralControl(Cell2Text)) 'Add the cells to the row. row.Cells.Add(cell2) Return row End Function 'BuildNewRow </script> <head> <body> <table id="ErrorTable" CellPadding=5 CellSpacing=0 Border="1" BorderColor="black" runat="server" /> </body> [C#] <%@ Import Namespace="System.Web.Services.Protocols" %> <%@ Import Namespace="System.Xml" %> <%@ Page Language="C#" %> <html> <head> <script runat=server language=c#> void Page_Load(Object o, EventArgs e){ // Create a new instance of the XML Web service proxy class. ThrowSoapException throwSoapException = new ThrowSoapException(); // Make a call to the XML Web service method, which throws an // exception. try { throwSoapException.myThrow(); } catch (SoapException error) { // Populate the table with the exception details. ErrorTable.Rows.Add(BuildNewRow("Fault Code Namespace", error.Code.Namespace)); ErrorTable.Rows.Add(BuildNewRow("Fault Code Name", error.Code.Name)); ErrorTable.Rows.Add(BuildNewRow( "SOAP Actor that threw Exception", error.Actor)); ErrorTable.Rows.Add(BuildNewRow("Error Message", error.Message)); ErrorTable.Rows.Add(BuildNewRow("Detail", HttpUtility.HtmlEncode(error.Detail.OuterXml))); return; } } // This populates a row in an HtmlTable. HtmlTableRow BuildNewRow(string Cell1Text, string Cell2Text) { HtmlTableRow row = new HtmlTableRow(); HtmlTableCell cell1 = new HtmlTableCell(); HtmlTableCell cell2 = new HtmlTableCell(); //Set the contents of the two cells. cell1.Controls.Add(new LiteralControl(Cell1Text)); //Add a cell to the row. row.Cells.Add(cell1); cell2.Controls.Add(new LiteralControl(Cell2Text)); //Add a cell to the row. row.Cells.Add(cell2); return row; } </script> <head> <body> <table id="ErrorTable" CellPadding=5 CellSpacing=0 Border="1" BorderColor="black" runat="server" /> </body>
Excepciones no controladas por un método de servicio Web XML
En la tabla siguiente se describe cómo se controla una excepción en ASP.NET si un método de servicio Web XML no detecta la excepción que se produce en el método.
Si la excepción se produce | En ASP.NET ocurre lo siguiente |
---|---|
Durante la ejecución del método de servicio Web XML | ASP.NET detecta la excepción y la inicia en el cliente. El cliente de servicios Web XML creado mediante .NET Framework recibe una excepción SoapException con la excepción específica colocada en la propiedad InnerException. |
Durante el procesamiento de encabezados SOAP | ASP.NET inicia una excepción SoapHeaderException. Un cliente de servicios Web XML creado mediante .NET Framework recibe la excepción SoapHeaderException. |
Vea también
SoapException (Clase) | SoapHeaderException (Clase) | Controlar e iniciar excepciones | Generar servicios Web XML mediante ASP. NET | Generar clientes de servicios Web XML