Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los errores de SOAP transportan información de condición de errores desde un servicio a un cliente y, en caso de comunicación dúplex, desde un cliente a un servicio de manera interoperable. Normalmente, un servicio define contenido de error personalizado y especifica qué operaciones pueden devolverlas. (Para obtener más información, vea Definición y especificación de errores). En este tema se describe cómo un servicio o cliente dúplex puede enviar esos errores cuando se ha producido la condición de error correspondiente y cómo una aplicación de cliente o servicio controla estos errores. Para obtener información general sobre el control de errores en las aplicaciones de Windows Communication Foundation (WCF), consulta Especificar y controlar errores en contratos y servicios.
Envío de errores SOAP
Los errores SOAP declarados son aquellos en los que una operación tiene un System.ServiceModel.FaultContractAttribute que especifica un tipo de error SOAP personalizado. Los errores SOAP no declarados son aquellos que no se especifican en el contrato para una operación.
Envío de errores declarados
Para enviar un error de SOAP declarado, detecte la condición de error para la que el error de SOAP es adecuado y genere una nueva System.ServiceModel.FaultException<TDetail>, donde el parámetro de tipo es un nuevo objeto del tipo especificado en FaultContractAttribute para esa operación. En el ejemplo de código siguiente se muestra el uso de FaultContractAttribute para especificar que la SampleMethod operación puede devolver un error SOAP con el tipo de detalle de GreetingFault.
[OperationContract]
[FaultContractAttribute(
typeof(GreetingFault),
Action="http://www.contoso.com/GreetingFault",
ProtectionLevel=ProtectionLevel.EncryptAndSign
)]
string SampleMethod(string msg);
<OperationContract, FaultContractAttribute(GetType(GreetingFault), Action:="http://www.contoso.com/GreetingFault", ProtectionLevel:=ProtectionLevel.EncryptAndSign)> _
Function SampleMethod(ByVal msg As String) As String
Para transmitir la información de GreetingFault error al cliente, capture la condición de error adecuada y lance un nuevo System.ServiceModel.FaultException<TDetail> de tipo GreetingFault con un objeto GreetingFault nuevo como argumento, como en el ejemplo de código siguiente. Si el cliente es una aplicación cliente WCF, experimenta esto como una excepción administrada donde el tipo es System.ServiceModel.FaultException<TDetail> de tipo GreetingFault.
throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg));
Throw New FaultException(Of GreetingFault)(New GreetingFault("A Greeting error occurred. You said: " & msg))
End If
Envío de errores no declarados
Enviar errores no declarados puede ser muy útil para diagnosticar y depurar rápidamente problemas en aplicaciones WCF, pero su utilidad como herramienta de depuración es limitada. Más generalmente, se recomienda al depurar que utilice la propiedad ServiceDebugBehavior.IncludeExceptionDetailInFaults. Al establecer este valor en true, los clientes experimentan tales errores como excepciones FaultException<TDetail> de tipo ExceptionDetail.
Importante
Dado que las excepciones administradas pueden exponer información interna de la aplicación, establecer ServiceBehaviorAttribute.IncludeExceptionDetailInFaults o ServiceDebugBehavior.IncludeExceptionDetailInFaults en true puede permitir que los clientes WCF obtengan información sobre las excepciones internas de las operaciones del servicio, incluida la identificación personal u otra información confidencial.
Por lo tanto, solo se recomienda establecer ServiceBehaviorAttribute.IncludeExceptionDetailInFaults o ServiceDebugBehavior.IncludeExceptionDetailInFaults en true como forma de depurar temporalmente una aplicación de servicio. Además, el WSDL de un método que devuelve excepciones administradas no controladas de esta manera no contiene el contrato para la FaultException<TDetail> de tipo ExceptionDetail. Los clientes deben contar con la posibilidad de que se produzca un error de SOAP desconocido (devuelto a los clientes WCF como objetos System.ServiceModel.FaultException) para obtener correctamente la información de depuración.
Para enviar una excepción SOAP no declarada, arroje un objeto System.ServiceModel.FaultException (es decir, no el tipo genérico FaultException<TDetail>) y pase la cadena al constructor. Esto se expone a las aplicaciones cliente WCF como una excepción lanzada System.ServiceModel.FaultException en la que la cadena está disponible llamando al método FaultException<TDetail>.ToString.
Nota:
Si declara un error de SOAP de tipo cadena y luego lo lanza en su servicio como un FaultException<TDetail>, donde el parámetro de tipo es un System.String, el valor de cadena se asigna a la propiedad FaultException<TDetail>.Detail y no está disponible desde FaultException<TDetail>.ToString.
Control de errores
En los clientes WCF, los errores SOAP que se producen durante la comunicación que interesan a las aplicaciones cliente se generan como excepciones administradas. Aunque hay muchas excepciones que pueden producirse durante la ejecución de cualquier programa, las aplicaciones que usan el modelo de programación de cliente WCF pueden esperar controlar las excepciones de los dos tipos siguientes como resultado de la comunicación.
Los objetos TimeoutException se producen cuando una operación supera el período de tiempo de espera especificado.
CommunicationException Los objetos se lanzan cuando hay alguna condición de error de comunicación recuperable en el servicio o en el cliente.
La CommunicationException clase tiene dos tipos FaultException derivados importantes y el tipo genérico FaultException<TDetail> .
Las excepciones FaultException se producen cuando un agente de escucha recibe un error que no se espera o especifica en el contrato de operación; normalmente esto sucede cuando se depura la aplicación y el servicio tiene la propiedad ServiceDebugBehavior.IncludeExceptionDetailInFaults establecida en true.
FaultException<TDetail> Las excepciones se lanzan en el cliente cuando se recibe un error especificado en el contrato de operación en respuesta a una operación de dos vías (es decir, un método con un atributo OperationContractAttribute donde IsOneWay está establecido en false).
Nota:
Cuando un servicio WCF tiene la propiedad ServiceBehaviorAttribute.IncludeExceptionDetailInFaults o ServiceDebugBehavior.IncludeExceptionDetailInFaults establecida en true, el cliente experimenta esto como una FaultException<TDetail> no declarada de tipo ExceptionDetail. Los clientes pueden detectar este error concreto o administrar el error en un bloque de detección de FaultException.
Normalmente, solo FaultException<TDetail>, TimeoutException y CommunicationException las excepciones son de interés para los clientes y servicios.
Nota:
Se producen otras excepciones, por supuesto. Entre las excepciones inesperadas se incluyen errores catastróficos como System.OutOfMemoryException; normalmente, las aplicaciones no deben detectar estos métodos.
Detectar excepciones de errores en el orden correcto
Dado que FaultException<TDetail> deriva de FaultExceptiony FaultException deriva de CommunicationException, es importante detectar estas excepciones en el orden adecuado. Por ejemplo, si tiene un bloque de intento/detección en el que primero detecta CommunicationException, todos los errores SOAP especificados y no especificados se administran ahí; los bloques de detección posteriores para administrar una excepción FaultException<TDetail> personalizada nunca se invocan.
Recuerde que una operación puede devolver un número indefinido de errores especificados. Cada error es un tipo único y se debe controlar por separado.
Administre las excepciones al cerrar el canal
La mayoría de las discusiones anteriores tienen que ver con los errores enviados en el transcurso del procesamiento de mensajes de aplicación, es decir, los mensajes enviados explícitamente por el cliente cuando la aplicación cliente llama a las operaciones en el objeto de cliente WCF.
Incluso con la disposición de objetos locales, el objeto puede elevar o enmascara excepciones que tienen lugar durante el proceso de reciclaje. Se puede producir algo similar cuando se usan objetos de cliente WCF. Llamar a operaciones implica enviar mensajes mediante una conexión establecida. El cierre del canal puede producir excepciones si la conexión no se puede cerrar de forma limpia o ya está cerrada, aunque todas las operaciones se devuelvan correctamente.
Normalmente, los canales de objetos de cliente se cierran de una de las maneras siguientes:
Cuando se recicla el objeto de cliente WCF.
Cuando la aplicación cliente llama a ClientBase<TChannel>.Close.
Cuando la aplicación cliente llama a ICommunicationObject.Close.
Cuando la aplicación de cliente llama a una operación que es una operación de finalización para una sesión.
En todos los casos, al cerrar el canal se indica al canal que empiece a cerrar los canales subyacentes que puedan enviar mensajes para admitir funcionalidad compleja en el nivel de aplicación. Por ejemplo, cuando un contrato requiere sesiones, un enlace intenta establecer una sesión mediante el intercambio de mensajes con el canal del servicio hasta que se establezca una sesión. Cuando se cierra el canal, el canal de sesión subyacente notifica al servicio que finaliza la sesión. En este caso, si el canal ya ha sido anulado, cerrado, o de otro modo no se puede usar (por ejemplo, cuando un cable de red está desconectado), el canal de cliente no puede informar al canal de servicio de que la sesión ha finalizado, lo que podría dar lugar a una excepción.
Anular el canal si es necesario
Dado que cerrar el canal también puede producir excepciones, se recomienda que además de detectar las excepciones de error en el orden correcto, es importante anular el canal que se utilizó para realizar la llamada en el bloque de detección.
Si el error transmite información de error específica de una operación y sigue siendo posible que otras personas puedan usarla, no es necesario anular el canal (aunque estos casos son poco frecuentes). En todos los demás casos, se recomienda interrumpir el canal. Para obtener un ejemplo que muestre todos estos puntos, consulte Excepciones esperadas.
En el ejemplo de código siguiente se muestra cómo controlar las excepciones de error soap en una aplicación cliente básica, incluido un error declarado y un error no declarado.
Nota:
Este código de ejemplo no usa la using construcción . Dado que los canales de cierre pueden producir excepciones, se recomienda que las aplicaciones creen primero un cliente WCF y, a continuación, abran, usen y cierren el cliente WCF en el mismo bloque try. Para obtener más información, consulte Información general del cliente WCF y Usar Cerrar y Abortar para liberar recursos del cliente WCF.
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;
public class Client
{
public static void Main()
{
// Picks up configuration from the config file.
SampleServiceClient wcfClient = new SampleServiceClient();
try
{
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));
Console.WriteLine("Press ENTER to exit:");
Console.ReadLine();
// Done with service.
wcfClient.Close();
Console.WriteLine("Done!");
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException<GreetingFault> greetingFault)
{
Console.WriteLine(greetingFault.Detail.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException unknownFault)
{
Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
Console.ReadLine();
wcfClient.Abort();
}
}
}
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation
Public Class Client
Public Shared Sub Main()
' Picks up configuration from the config file.
Dim wcfClient As New SampleServiceClient()
Try
' Making calls.
Console.WriteLine("Enter the greeting to send: ")
Dim greeting As String = Console.ReadLine()
Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))
Console.WriteLine("Press ENTER to exit:")
Console.ReadLine()
' Done with service.
wcfClient.Close()
Console.WriteLine("Done!")
Catch timeProblem As TimeoutException
Console.WriteLine("The service operation timed out. " & timeProblem.Message)
Console.ReadLine()
wcfClient.Abort()
Catch greetingFault As FaultException(Of GreetingFault)
Console.WriteLine(greetingFault.Detail.Message)
Console.ReadLine()
wcfClient.Abort()
Catch unknownFault As FaultException
Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
Console.ReadLine()
wcfClient.Abort()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
Console.ReadLine()
wcfClient.Abort()
End Try
End Sub
End Class