Senden und Empfangen von FehlernSending and Receiving Faults

SOAP-Fehler vermitteln Informationen über Fehlerbedingungen von einem Dienst an einen Client und bei Duplexkommunikation von einem Client an einen Dienst in einem interoperablen Verfahren.SOAP faults convey error condition information from a service to a client and in the duplex case from a client to a service in an interoperable way. In der Regel definiert ein Dienst benutzerdefinierten Fehlerinhalt und legt fest, welche Vorgänge ihn zurückgeben können.Typically a service defines custom fault content and specifies which operations can return them. (Weitere Informationen finden Sie unter definieren und Angeben von Fehlern.) In diesem Thema wird erläutert, wie ein Dienst oder ein Duplexclient diese Fehler senden kann, wenn der entsprechende Fehlerzustand aufgetreten ist, und wie eine Client- oder Dienstanwendung diese Fehler verarbeitet.(For more information, see Defining and Specifying Faults.) This topic discusses how a service or duplex client can send those faults when the corresponding error condition has occurred and how a client or service application handles these faults. Einen Überblick über die Fehlerbehandlung in Windows Communication Foundation (WCF)-Anwendungen finden Sie unter angeben und Behandeln von Fehlern in Verträgen und Diensten.For an overview of error handling in Windows Communication Foundation (WCF) applications, see Specifying and Handling Faults in Contracts and Services.

Senden von SOAP-FehlernSending SOAP Faults

Bei deklarierten SOAP-Fehlern verfügt ein Vorgang über ein System.ServiceModel.FaultContractAttribute, das einen benutzerdefinierten SOAP-Fehlertyp angibt.Declared SOAP faults are those in which an operation has a System.ServiceModel.FaultContractAttribute that specifies a custom SOAP fault type. Nicht deklarierte SOAP-Fehler sind Fehler, die nicht im Vertrag eines Vorgangs festgelegt sind.Undeclared SOAP faults are those that are not specified in the contract for an operation.

Senden von deklarierten FehlernSending Declared Faults

Um einen deklarierten SOAP-Fehler zu senden, erkennen Sie die Fehlerbedingung, zu der der SOAP-Fehler passt, und lösen Sie eine neue System.ServiceModel.FaultException<TDetail> aus, bei der der Typparameter ein neues Objekt des Typs ist, der im FaultContractAttribute für diesen Vorgang angegeben ist.To send a declared SOAP fault, detect the error condition for which the SOAP fault is appropriate and throw a new System.ServiceModel.FaultException<TDetail> where the type parameter is a new object of the type specified in the FaultContractAttribute for that operation. Im folgenden Codebeispiel wird veranschaulicht, wie mit dem FaultContractAttribute angegeben werden kann, dass der SampleMethod-Vorgang einen SOAP-Fehler mit dem Detailtyp GreetingFault zurückgeben kann.The following code example shows the use of FaultContractAttribute to specify that the SampleMethod operation can return a SOAP fault with the detail type of 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

Um die GreetingFault-Fehlerinformation an den Client zu übermitteln, fangen Sie die entsprechende Fehlerbedingung ab, und lösen Sie eine System.ServiceModel.FaultException<TDetail> vom Typ GreetingFault mit einem neuen GreetingFault-Objekt als Argument aus, wie im folgenden Codebeispiel dargestellt.To convey the GreetingFault error information to the client, catch the appropriate error condition and throw a new System.ServiceModel.FaultException<TDetail> of type GreetingFault with a new GreetingFault object as the argument, as in the following code example. Wenn der Client eine WCF-Clientanwendung befindet, erfährt er dies als eine verwaltete Ausnahme, wobei der Typ ist System.ServiceModel.FaultException<TDetail> vom Typ GreetingFault.If the client is an WCF client application, it experiences this as a managed exception where the type is System.ServiceModel.FaultException<TDetail> of 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

Senden von undeklarierten FehlernSending Undeclared Faults

Senden von undeklarierte Fehlern können sehr hilfreich sein, schnell zu diagnostizieren und zu debuggen Probleme mit WCF-Anwendungen, aber sein nutzen als Debugtool begrenzt ist.Sending undeclared faults can be very useful to quickly diagnose and debug problems in WCF applications, but its usefulness as a debugging tool is limited. Allgemeiner gesagt, ist es empfehlenswert, beim Debuggen die ServiceDebugBehavior.IncludeExceptionDetailInFaults-Eigenschaft zu verwenden.More generally, when debugging it is recommended that you use the ServiceDebugBehavior.IncludeExceptionDetailInFaults property. Wenn Sie diesen Wert auf true festlegen, erfahren Clients solche Fehler als FaultException<TDetail>-Ausnahmen des Typs ExceptionDetail.When you set this value to true, clients experience such faults as FaultException<TDetail> exceptions of type ExceptionDetail.

Wichtig

Da mit verwaltete Ausnahmen interne Anwendungsinformationen verfügbar machen können, der Festlegung ServiceBehaviorAttribute.IncludeExceptionDetailInFaults oder ServiceDebugBehavior.IncludeExceptionDetailInFaults auf true ermöglicht WCF-Clients zum Abrufen von Informationen über interne dienstvorgangsausnahmen, einschließlich persönlich identifizierbarer oder anderer vertraulicher Informationen.Because managed exceptions can expose internal application information, setting ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or ServiceDebugBehavior.IncludeExceptionDetailInFaults to true can permit WCF clients to obtain information about internal service operation exceptions, including personally identifiable or other sensitive information.

Daher wird die Festlegung von ServiceBehaviorAttribute.IncludeExceptionDetailInFaults für ServiceDebugBehavior.IncludeExceptionDetailInFaults oder true nur für das vorübergehende Debuggen einer Dienstanwendung empfohlen.Therefore, setting ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or ServiceDebugBehavior.IncludeExceptionDetailInFaults to true is only recommended as a way of temporarily debugging a service application. Außerdem beinhaltet die WSDL für eine Methode, die nicht behandelte verwaltete Ausnahmen auf diese Weise zurückgibt, keinen Vertrag für die FaultException<TDetail> vom Typ ExceptionDetail.In addition, the WSDL for a method that returns unhandled managed exceptions in this way does not contain the contract for the FaultException<TDetail> of type ExceptionDetail. Clients müssen erwarten, dass die Möglichkeit, einen unbekannten SOAP-Fehler (für WCF-Clients als zurückgegeben System.ServiceModel.FaultException Objekte), die Debuginformationen korrekt abrufen.Clients must expect the possibility of an unknown SOAP fault (returned to WCF clients as System.ServiceModel.FaultException objects) to obtain the debugging information properly.

Um einen undeklarierten SOAP-Fehler zu senden, lösen Sie ein System.ServiceModel.FaultException-Objekt aus (d. h. nicht den generischen Typ FaultException<TDetail>), und übergeben Sie die Zeichenfolge dem Konstruktor.To send an undeclared SOAP fault, throw a System.ServiceModel.FaultException object (that is, not the generic type FaultException<TDetail>) and pass the string to the constructor. Wird verfügbar gemacht, die WCF-Clientanwendungen als eine ausgelöste System.ServiceModel.FaultException Ausnahme, in die Zeichenfolge durch Aufrufen steht, der FaultException<TDetail>.ToString Methode.This is exposed to the WCF client applications as a thrown System.ServiceModel.FaultException exception where the string is available by calling the FaultException<TDetail>.ToString method.

Hinweis

Wenn Sie einen SOAP-Fehler vom Typ Zeichenfolge deklarieren und dies dann in Ihrem Service als FaultException<TDetail> auslösen, wobei der Typparameter eine System.String ist, wird der Zeichenfolgenwert der FaultException<TDetail>.Detail-Eigenschaft zugewiesen und ist nicht über FaultException<TDetail>.ToString verfügbar.If you declare a SOAP fault of type string, and then throw this in your service as a FaultException<TDetail> where the type parameter is a System.String the string value is assigned to the FaultException<TDetail>.Detail property, and is not available from FaultException<TDetail>.ToString.

Behandeln von FehlernHandling Faults

SOAP-Fehler, die auftreten, während der Kommunikation, die für Clientanwendungen relevant sind, werden in WCF-Clients als verwaltete Ausnahmen ausgelöst.In WCF clients, SOAP faults that occur during communication that are of interest to client applications are raised as managed exceptions. Dafür gibt es viele Ausnahmen, die während der Ausführung eines Programms auftreten können, können Anwendungen, die über das Programmiermodell für die WCF-Client davon ausgehen, Ausnahmen von den folgenden zwei Typen als kommunikationsergebnis behandeln.While there are many exceptions that can occur during the execution of any program, applications using the WCF client programming model can expect to handle exceptions of the following two types as a result of communication.

TimeoutException-Objekte werden ausgelöst, wenn ein Vorgang das angegebene Zeitlimit überschreitet.TimeoutException objects are thrown when an operation exceeds the specified timeout period.

CommunicationException-Objekte werden ausgelöst, wenn entweder beim Dienst oder beim Client eine behebbare Kommunikationsfehlerbedingung besteht.CommunicationException objects are thrown when there is some recoverable communication error condition on either the service or the client.

Die CommunicationException-Klasse verfügt über zwei wichtige abgeleitete Typen: FaultException und den generischen FaultException<TDetail>-Typ.The CommunicationException class has two important derived types, FaultException and the generic FaultException<TDetail> type.

FaultException-Ausnahmen werden ausgelöst, wenn ein Listener einen Fehler empfängt, der in dem Vorgangsvertrag nicht erwartet oder festgelegt ist; dies geschieht normalerweise, wenn die Anwendung gedebuggt wird und die ServiceDebugBehavior.IncludeExceptionDetailInFaults-Eigenschaft des Diensts auf true festgelegt ist.FaultException exceptions are thrown when a listener receives a fault that is not expected or specified in the operation contract; usually this occurs when the application is being debugged and the service has the ServiceDebugBehavior.IncludeExceptionDetailInFaults property set to true.

Am Client werden FaultException<TDetail>-Ausnahmen ausgelöst, wenn ein im Vorgangsvertrag angegebener Fehler als Antwort auf einen bidirektionalen Vorgang empfangen wird (d. h. eine Methode mit einem OperationContractAttribute-Attribut, bei dem IsOneWay auf false festgelegt ist).FaultException<TDetail> exceptions are thrown on the client when a fault that is specified in the operation contract is received in response to a two-way operation (that is, a method with an OperationContractAttribute attribute with IsOneWay set to false).

Hinweis

Wenn ein WCF-Dienst hat die ServiceBehaviorAttribute.IncludeExceptionDetailInFaults oder ServiceDebugBehavior.IncludeExceptionDetailInFaults -Eigenschaftensatz auf true der Client erfährt dieses als eine undeklarierte FaultException<TDetail> vom Typ ExceptionDetail.When an WCF service has the ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or ServiceDebugBehavior.IncludeExceptionDetailInFaults property set to true the client experiences this as an undeclared FaultException<TDetail> of type ExceptionDetail. Clients können diesen bestimmten Fehler entweder abfangen oder den Fehler in einem Catch-Block für FaultException behandeln.Clients can either catch this specific fault or handle the fault in a catch block for FaultException.

In der Regel sind nur FaultException<TDetail>-, TimeoutException- und CommunicationException-Ausnahmen für Clients und Dienste relevant.Typically, only FaultException<TDetail>, TimeoutException, and CommunicationException exceptions are of interest to clients and services.

Hinweis

Es treten natürlich andere Ausnahmen auf.Other exceptions, of course, do occur. Unerwartete Ausnahmen schließen schwerwiegende Fehler wie System.OutOfMemoryException ein; in der Regel sollten Anwendungen solche Methoden nicht abfangen.Unexpected exceptions include catastrophic failures like System.OutOfMemoryException; typically applications should not catch such methods.

Abfangen von Fehlerausnahmen in der richtigen ReihenfolgeCatch Fault Exceptions in the Correct Order

Da FaultException<TDetail> von FaultException abgeleitet wird und FaultException von CommunicationException abgeleitet wird, müssen diese Ausnahmen in der richtigen Reihenfolge abgefangen werden.Because FaultException<TDetail> derives from FaultException, and FaultException derives from CommunicationException, it is important to catch these exceptions in the proper order. Bei einem try/catch-Block, bei dem zuerst CommunicationException abgefangen wird, werden z. B. alle angegebenen und nicht angegebenen SOAP-Fehler dort behandelt; nachfolgende catch-Blöcke zum Behandeln einer benutzerdefinierten FaultException<TDetail>-Ausnahme werden niemals aufgerufen.If, for example, you have a try/catch block in which you first catch CommunicationException, all specified and unspecified SOAP faults are handled there; any subsequent catch blocks to handle a custom FaultException<TDetail> exception are never invoked.

Vergessen Sie nicht, dass ein Vorgang eine beliebige Anzahl angegebener Fehler zurückgeben kann.Remember that one operation can return any number of specified faults. Jeder Fehler ist ein eindeutiger Typ und muss getrennt behandelt werden.Each fault is a unique type and must be handled separately.

Behandeln von Ausnahmen beim Schließen des KanalsHandle Exceptions When Closing the Channel

Die meisten die vorangegangenen erläuterungen muss mit Fehlern, die im Verlauf der Verarbeitung von Anwendungsnachrichten, d. h. gesendet nur Nachrichten, die explizit vom Client gesendet werden, wenn die Clientanwendung Vorgänge für den WCF-Clientobjekts aufruft.Most of the preceding discussion has to do with faults sent in the course of processing application messages, that is, messages explicitly sent by the client when the client application calls operations on the WCF client object.

Sogar lokale Objekte, die das Objekt verwerfen, können Ausnahmen, die während des Wiederverwendungsprozesses auftreten, entweder auslösen oder maskieren.Even with local objects disposing the object can either raise or mask exceptions that occur during the recycling process. Etwas Ähnliches kann auftreten, wenn Sie WCF-Client-Objekte verwenden.Something similar can occur when you use WCF client objects. Wenn Sie Vorgänge aufrufen, senden Sie Nachrichten über eine hergestellte Verbindung.When you call operations you are sending messages over an established connection. Das Schließen des Kanals kann Ausnahmen auslösen, wenn die Verbindung nicht ordnungsgemäß getrennt wird oder bereits getrennt ist, selbst wenn alle Vorgänge ordnungsgemäß zurückgegeben werden.Closing the channel can throw exceptions if the connection cannot be cleanly closed or is already closed, even if all the operations returned properly.

In der Regel werden Clientobjektkanäle auf eine der folgenden Möglichkeiten geschlossen:Typically, client object channels are closed in one of the following ways:

  • Wenn der WCF-Clientobjekt wiederverwendet wird.When the WCF client object is recycled.

  • Wenn die Clientanwendung ClientBase<TChannel>.Close aufruft.When the client application calls ClientBase<TChannel>.Close.

  • Wenn die Clientanwendung ICommunicationObject.Close aufruft.When the client application calls ICommunicationObject.Close.

  • Wenn die Clientanwendung einen Vorgang aufruft, bei dem es sich um einen Vorgang handelt, der eine Sitzung beendet.When the client application calls an operation that is a terminating operation for a session.

In jedem Fall weist das Schließen des Kanals den Kanal an zu beginnen, alle zugrunde liegenden Kanäle zu schließen, die möglicherweise Nachrichten senden, um eine komplexe Funktionalität auf Anwendungsebene zu unterstützen.In all cases, closing the channel instructs the channel to begin closing any underlying channels that may be sending messages to support complex functionality at the application level. Wenn z. B. ein Vertrag Sitzungen erfordert, versucht eine Bindung eine Sitzung einzurichten, indem Nachrichten mit dem Dienstkanal ausgetauscht werden, bis eine Sitzung eingerichtet ist.For example, when a contract requires sessions a binding attempts to establish a session by exchanging messages with the service channel until a session is established. Wenn der Kanal geschlossen wird, benachrichtigt der zugrunde liegende Sitzungskanal den Dienst, dass die Sitzung beendet wird.When the channel is closed, the underlying session channel notifies the service that the session is terminated. Wenn der Kanal bereits abgebrochen oder geschlossen ist oder aus anderen Gründen nicht verwendet werden kann (z. B. wenn ein Netzwerkkabel abgezogen wird), kann der Clientkanal dem Dienstkanal in diesem Fall nicht mitteilen, dass die Sitzung beendet wird, und dies kann zu einer Ausnahme führen.In this case, if the channel has already aborted, closed, or is otherwise unusable (for example, when a network cable is unplugged), the client channel cannot inform the service channel that the session is terminated and an exception can result.

Abbrechen des Kanals (falls erforderlich)Abort the Channel If Necessary

Da das Schließen des Kanals auch Ausnahmen auslösen kann, wird empfohlen, den Kanal, der für den Aufruf in dem catch-Block verwendet wurde, zusätzlich zum Abfangen von Fehlerausnahmen in der richtigen Reihenfolge abzubrechen.Because closing the channel can also throw exceptions, then, it is recommended that in addition to catching fault exceptions in the correct order, it is important to abort the channel that was used in making the call in the catch block.

Wenn der Fehler Fehlerinformationen übermittelt, die für einen Vorgang spezifisch sind, und andere ihn möglicherweise verwenden können, muss der Kanal nicht abgebrochen werden (obwohl dies selten vorkommt).If the fault conveys error information specific to an operation and it remains possible that others can use it, there is no need to abort the channel (although these cases are rare). In allen anderen Fällen wird empfohlen, den Kanal abzubrechen.In all other cases, it is recommended that you abort the channel. Ein Beispiel, das alle diese Punkte veranschaulicht, finden Sie unter Ausnahmen erwartet.For a sample that demonstrates all of these points, see Expected Exceptions.

Das folgende Codebeispiel veranschaulicht die Behandlung von SOAP-Fehlerausnahmen in einer grundlegenden Clientanwendung einschließlich eines deklarierten Fehlers und eines undeklarierten Fehlers.The following code example shows how to handle SOAP fault exceptions in a basic client application, including a declared fault and an undeclared fault.

Hinweis

Dieser Beispielcode verwendet kein using-Konstrukt.This sample code does not use the using construct. Da das Schließen von Kanälen Ausnahmen auslösen kann, empfiehlt es sich, dass Anwendungen erstellen Sie einen WCF-Client zuerst und dann geöffnet ist, verwenden, und Schließen des WCF-Clients in derselben try-Block.Because closing channels can throw exceptions, it is recommended that applications create a WCF client first, and then open, use, and close the WCF client in the same try block. Weitere Informationen finden Sie unter Überblick über WCF-Client und Vermeiden von Problemen mit der Using-Anweisung.For details, see WCF Client Overview and Avoiding Problems with the Using Statement.

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
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

Siehe auchSee Also

FaultException
FaultException<TDetail>
System.ServiceModel.CommunicationException
Erwartete AusnahmenExpected Exceptions
Vermeiden von Problemen mit der using-AnweisungAvoiding Problems with the Using Statement