Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les erreurs SOAP acheminent des informations de condition d'erreur d'un service à un client et, dans le cas duplex, d'un client à un service d'une manière interopérable. En règle générale, un service définit le contenu d’erreur personnalisé et spécifie les opérations qui peuvent les retourner. (Pour plus d’informations, consultez Définition et spécification des erreurs.) Cette rubrique explique comment un service ou un client duplex peut envoyer ces erreurs lorsque la condition d’erreur correspondante s’est produite et comment une application cliente ou de service gère ces erreurs. Pour obtenir une vue d’ensemble de la gestion des erreurs dans les applications Windows Communication Foundation (WCF), consultez Spécification et gestion des erreurs dans les contrats et services.
Envoi d'erreurs SOAP
Les erreurs SOAP déclarées sont celles dans lesquelles une opération a un System.ServiceModel.FaultContractAttribute type d’erreur SOAP personnalisé. Les erreurs SOAP non déclarées sont celles qui ne sont pas spécifiées dans le contrat pour une opération.
Envoi d’erreurs déclarées
Pour envoyer une erreur SOAP déclarée, détectez la condition d’erreur pour laquelle l’erreur SOAP est appropriée et lancez un nouvel System.ServiceModel.FaultException<TDetail> où le paramètre de type est un nouvel objet du type spécifié dans le FaultContractAttribute pour cette opération. L’exemple de code suivant montre l’utilisation de FaultContractAttribute pour spécifier que l’opération SampleMethod peut retourner une erreur SOAP avec le type de détail 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
Pour acheminer les informations sur l'erreur GreetingFault au client, interceptez la condition d'erreur appropriée et levez une nouvelle System.ServiceModel.FaultException<TDetail> de type GreetingFault avec un nouvel objet GreetingFault comme argument, comme dans l'exemple de code suivant. Si le client est une application cliente WCF, il fait l’objet d’une exception gérée où le type est System.ServiceModel.FaultException<TDetail> de type 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
Envoi de défauts non déclarés
L’envoi d’erreurs non déclarées peut être très utile pour diagnostiquer et déboguer rapidement les problèmes dans les applications WCF, mais son utilité en tant qu’outil de débogage est limité. Plus généralement, lors du débogage, il est recommandé d’utiliser la ServiceDebugBehavior.IncludeExceptionDetailInFaults propriété. Lorsque vous définissez cette valeur à « true », les clients rencontrent des erreurs telles que des exceptions FaultException<TDetail> de type ExceptionDetail.
Importante
Étant donné que les exceptions managées peuvent exposer des informations internes de l'application, définir ServiceBehaviorAttribute.IncludeExceptionDetailInFaults ou ServiceDebugBehavior.IncludeExceptionDetailInFaults peut permettre aux clients WCF d'obtenir des informations sur les exceptions des opérations de service internes, y compris des informations personnellement identifiables ou d'autres informations sensibles.
Par conséquent, il est uniquement recommandé de définir ServiceBehaviorAttribute.IncludeExceptionDetailInFaults ou ServiceDebugBehavior.IncludeExceptionDetailInFaults sur true comme un moyen de déboguer temporairement une application de service. En outre, le WSDL pour une méthode qui retourne des exceptions managées non gérées de cette façon ne contient pas le contrat pour le FaultException<TDetail> type ExceptionDetail. Les clients doivent s’attendre à la possibilité d’une erreur SOAP inconnue (retournée aux clients WCF en tant qu’objets System.ServiceModel.FaultException ) pour obtenir correctement les informations de débogage.
Pour envoyer une erreur SOAP non déclarée, lancez un System.ServiceModel.FaultException objet (autrement dit, pas le type FaultException<TDetail> générique) et transmettez la chaîne au constructeur. Cette exception est exposée aux applications clientes WCF en tant qu’exception System.ServiceModel.FaultException levée où la chaîne est disponible en appelant la méthode FaultException<TDetail>.ToString.
Remarque
Si vous déclarez une erreur SOAP de type chaîne et que vous la levez dans votre service en tant que FaultException<TDetail>, où le paramètre de type est un System.String, la valeur de chaîne est affectée à la propriété FaultException<TDetail>.Detail et n’est pas disponible depuis FaultException<TDetail>.ToString.
Gestion des erreurs
Dans les clients WCF, les erreurs SOAP qui se produisent pendant la communication qui sont intéressantes pour les applications clientes sont déclenchées en tant qu’exceptions managées. Bien qu’il existe de nombreuses exceptions qui peuvent se produire pendant l’exécution de n’importe quel programme, les applications utilisant le modèle de programmation client WCF peuvent s’attendre à gérer les exceptions des deux types suivants en raison de la communication.
TimeoutException les objets sont lancés lorsqu’une opération dépasse la période d’expiration spécifiée.
Les objets CommunicationException sont levés lorsqu'il existe une condition d'erreur de communication récupérable sur le service ou le client.
La CommunicationException classe a deux types dérivés importants, FaultException et le type générique FaultException<TDetail>.
FaultException les exceptions sont levées lorsqu’un écouteur reçoit une erreur qui n’est pas attendue ou spécifiée dans le contrat d’opération ; cela se produit généralement lorsque l’application est déboguée et que le service a la ServiceDebugBehavior.IncludeExceptionDetailInFaults propriété définie sur true.
Les exceptions FaultException<TDetail> sont levées sur le client lorsqu'une erreur spécifiée dans le contrat d'opération est reçue en réponse à une opération bidirectionnelle (autrement dit, une méthode avec un attribut OperationContractAttribute ayant la valeur IsOneWay affectée à false).
Remarque
Lorsqu’un service WCF a la propriété ServiceBehaviorAttribute.IncludeExceptionDetailInFaults ou ServiceDebugBehavior.IncludeExceptionDetailInFaults définie sur true, le client le perçoit comme un FaultException<TDetail> non déclaré de type ExceptionDetail. Les clients peuvent intercepter cette erreur spécifique ou gérer l'erreur dans un bloc catch pour FaultException.
En règle générale, seuls FaultException<TDetail>, TimeoutExceptionet CommunicationException les exceptions sont intéressants pour les clients et les services.
Remarque
D’autres exceptions, bien sûr, se produisent. Les exceptions inattendues incluent des défaillances catastrophiques telles que System.OutOfMemoryException ; généralement, les applications ne devraient pas intercepter de telles méthodes.
Interception des exceptions dans l'ordre correct
Étant donné que FaultException<TDetail> dérive de FaultException, et FaultException dérive de CommunicationException, il est important d’intercepter ces exceptions dans l’ordre approprié. Si, par exemple, vous disposez d’un bloc try/catch dans lequel vous interceptez CommunicationExceptiond’abord, toutes les erreurs SOAP spécifiées et non spécifiées y sont gérées ; tous les blocs catch suivants pour gérer une exception personnalisée FaultException<TDetail> ne sont jamais appelés.
N’oubliez pas qu’une opération peut retourner n’importe quel nombre d’erreurs spécifiées. Chaque erreur est un type unique et doit être gérée séparément.
Gérer les exceptions lors de la fermeture du canal
La plupart des discussions précédentes doivent être liés aux erreurs envoyées au cours du traitement des messages d’application, c’est-à-dire des messages envoyés explicitement par le client lorsque l’application cliente appelle des opérations sur l’objet client WCF.
Même avec les objets locaux, l'élimination de l'objet peut déclencher ou masquer des exceptions qui se produisent pendant le processus de recyclage. Quelque chose de similaire peut se produire lorsque vous utilisez des objets client WCF. Lorsque vous appelez des opérations, vous envoyez des messages via une connexion établie. La fermeture du canal peut lever des exceptions si la connexion ne peut pas être fermée proprement ou si elle est déjà fermée, même si toutes les opérations ont été retournées correctement.
En règle générale, les canaux d’objets clients sont fermés de l’une des manières suivantes :
Lorsque l’objet client WCF est recyclé.
Quand l’application cliente appelle ClientBase<TChannel>.Close.
Quand l’application cliente appelle ICommunicationObject.Close.
Lorsque l’application cliente appelle une opération qui est une opération de fin pour une session.
Dans tous les cas, la fermeture du canal indique au canal de commencer à fermer tous les canaux sous-jacents susceptibles d’envoyer des messages pour prendre en charge des fonctionnalités complexes au niveau de l’application. Par exemple, lorsqu’un contrat requiert des sessions, une liaison tente d’établir une session en échangeant des messages avec le canal de service jusqu’à ce qu’une session soit établie. Lorsque le canal est fermé, le canal de session sous-jacent informe le service que la session est arrêtée. Dans ce cas, si le canal a déjà abandonné, fermé ou est inutilisable (par exemple, lorsqu’un câble réseau est déconnecté), le canal client ne peut pas informer le canal de service que la session est arrêtée et qu’une exception peut se produire.
Abandonner le canal si nécessaire
La fermeture du canal pouvant également lever des exceptions, en plus d'intercepter les exceptions dans l'ordre correct il est important d'abandonner le canal utilisé pour effectuer l'appel dans le bloc catch.
Si l’erreur transmet des informations d’erreur spécifiques à une opération et qu’il reste possible que d’autres puissent l’utiliser, il n’est pas nécessaire d’abandonner le canal (bien que ces cas soient rares). Dans tous les autres cas, il est recommandé d’abandonner le canal. Pour obtenir un exemple qui illustre tous ces points, consultez Exceptions attendues.
L’exemple de code suivant montre comment gérer les exceptions d’erreur SOAP dans une application cliente de base, y compris une erreur déclarée et une erreur non déclarée.
Remarque
Cet exemple de code n’utilise pas la using construction. Étant donné que la fermeture des canaux peut lever des exceptions, il est recommandé que les applications commencent par créer un client WCF, puis l'ouvrent, l'utilisent et le ferment dans le même bloc try. Pour plus d’informations, consultez Vue d’ensemble du client WCF et utilisez Fermer et Abandonner pour libérer les ressources du client 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