Senden und Empfangen von Fehlern

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. In der Regel definiert ein Dienst benutzerdefinierten Fehlerinhalt und legt fest, welche Vorgänge ihn zurückgeben können. (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. Eine Übersicht über die Fehlerbehandlung bei Windows Communication Foundation (WCF)-Anwendungen finden Sie unter Angeben und Behandeln von Fehlern in Verträgen und Diensten.

Senden von SOAP-Fehlern

Bei deklarierten SOAP-Fehlern verfügt ein Vorgang über ein System.ServiceModel.FaultContractAttribute, das einen benutzerdefinierten SOAP-Fehlertyp angibt. Nicht deklarierte SOAP-Fehler sind jene, die nicht im Vertrag für eine Operation festgelegt werden.

Senden von deklarierten Fehlern

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 aus, bei der der Typparameter ein neues Objekt des Typs ist, der im FaultContractAttribute für diesen Vorgang angegeben ist. 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.

<OperationContract, FaultContractAttribute(GetType(GreetingFault), Action:="https://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 vom Typ GreetingFault mit einem neuen GreetingFault-Objekt als Argument aus, wie im folgenden Codebeispiel dargestellt. Wenn es sich bei dem Client um eine WCF-Clientanwendung handelt, erfährt er dies als verwaltete Ausnahme, wobei der Typ eine System.ServiceModel.FaultException vom Typ GreetingFault ist.

  Throw New FaultException(Of GreetingFault)(New GreetingFault("A Greeting error occurred. You said: " & msg))
End If

Senden von undeklarierten Fehlern

Das Senden von undeklarierten Fehlern kann sehr nützlich sein, um Probleme in WCF-Anwendungen schnell zu diagnostizieren und zu debuggen, aber sein Nutzen als Debugtool ist begrenzt. Allgemeiner gesagt, ist es empfehlenswert, beim Debuggen die System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults-Eigenschaft zu verwenden. Wenn Sie diesen Wert auf true festlegen, erfahren Clients solche Fehler als FaultException-Ausnahmen des Typs ExceptionDetail.

ms732013.Important(de-de,VS.100).gif Hinweis:
Da mit verwalteten Ausnahmen interne Anwendungsinformationen verfügbar gemacht werden können, kann mit der Festlegung von true für System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults oder System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults WCF-Clients gestattet werden, Informationen über interne Dienstvorgangsausnahmen, einschließlich persönlich identifizierbarer oder anderer vertraulicher Informationen, zu erhalten.

Daher wird die Festlegung von true für System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults oder System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults nur für das vorübergehende Debuggen einer Dienstanwendung empfohlen. 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 vom Typ ExceptionDetail. Clients müssen die Wahrscheinlichkeit eines unbekannten SOAP-Fehlers erwarten (an WCF-Clients als System.ServiceModel.FaultException-Objekte zurückgegeben), um die Debuginformationen richtig zu erhalten.

Um einen undeklarierten SOAP-Fehler zu senden, lösen Sie ein System.ServiceModel.FaultException-Objekt aus (d. h. nicht den generischen Typ FaultException), und übergeben Sie die Zeichenfolge dem Konstruktor. Dies wird für die WCF-Clientanwendungen als eine ausgelöste System.ServiceModel.FaultException-Ausnahme verfügbar gemacht, wobei die Zeichenfolge durch Aufrufen der System.ServiceModel.FaultException.ToString-Methode verfügbar ist.

ms732013.note(de-de,VS.100).gifHinweis:
Wenn Sie einen SOAP-Fehler vom Typ Zeichenfolge deklarieren und dies dann in Ihrem Service als FaultException auslösen, wobei der Typparameter eine System.String ist, wird der Zeichenfolgenwert der System.ServiceModel.FaultException.Detail-Eigenschaft zugewiesen und ist nicht über System.ServiceModel.FaultException.ToString verfügbar.

Behandeln von Fehlern

Bei WCF-Clients werden während einer Kommunikation auftretende SOAP-Fehler, die für Clientanwendungen relevant sind, als verwaltete Ausnahmen ausgelöst. Während es viele Ausnahmen gibt, die während der Ausführung eines Programms auftreten können, können Anwendungen, die das Programmiermodell des WCF-Clients verwenden, Ausnahmen der beiden folgenden Typen als Kommunikationsergebnis behandeln.

TimeoutException-Objekte werden ausgelöst, wenn ein Vorgang das angegebene Zeitlimit überschreitet.

CommunicationException-Objekte werden ausgelöst, wenn entweder beim Dienst oder beim Client eine behebbare Kommunikationsfehlerbedingung besteht.

Die CommunicationException-Klasse verfügt über zwei wichtige abgeleitete Typen: FaultException und den generischen FaultException-Typ.

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 System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults-Eigenschaft des Diensts auf true festgelegt ist.

Am Client werden FaultException-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).

ms732013.note(de-de,VS.100).gifHinweis:
Wenn für einen WCF-Dienst die System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults- oder die System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults-Eigenschaft auf true festgelegt ist, erfährt der Client dies als eine undeklarierte FaultException vom Typ ExceptionDetail. Clients können diesen bestimmten Fehler entweder abfangen oder den Fehler in einem Catch-Block für FaultException behandeln.

In der Regel sind nur FaultException-, TimeoutException- und CommunicationException-Ausnahmen für Clients und Dienste relevant.

ms732013.note(de-de,VS.100).gifHinweis:
Es treten natürlich andere Ausnahmen auf. Unerwartete Ausnahmen schließen schwerwiegende Fehler wie System.OutOfMemoryException ein; in der Regel sollten Anwendungen solche Methoden nicht abfangen.

Abfangen von Fehlerausnahmen in der richtigen Reihenfolge

Da FaultException von FaultException abgeleitet wird und FaultException von CommunicationException abgeleitet wird, müssen diese Ausnahmen in der richtigen Reihenfolge abgefangen werden. 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-Ausnahme werden niemals aufgerufen.

Vergessen Sie nicht, dass ein Vorgang eine beliebige Anzahl angegebener Fehler zurückgeben kann. Jeder Fehler ist ein eindeutiger Typ und muss getrennt behandelt werden.

Behandeln von Ausnahmen beim Schließen des Kanals

Der größte Teil der vorangehenden Erläuterung behandelt Fehler, die während der Verarbeitung von Anwendungsnachrichten gesendet werden, d. h. Nachrichten, die explizit vom Client gesendet werden, wenn die Clientanwendung Vorgänge für das WCF-Clientobjekt aufruft.

Sogar lokale Objekte, die das Objekt verwerfen, können Ausnahmen, die während des Wiederverwendungsprozesses auftreten, entweder auslösen oder maskieren. Etwas Ähnliches kann auftreten, wenn Sie WCF-Clientobjekte verwenden. Wenn Sie Vorgänge aufrufen, senden Sie Nachrichten über eine hergestellte Verbindung. 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.

In der Regel werden Clientobjektkanäle auf eine der folgenden Möglichkeiten geschlossen:

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. 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. Wenn der Kanal geschlossen wird, benachrichtigt der zugrunde liegende Sitzungskanal den Dienst, dass die Sitzung beendet wird. 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.

Abbrechen des Kanals (falls erforderlich)

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.

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). In allen anderen Fällen wird empfohlen, den Kanal abzubrechen. Eine Beispielanwendung, die all dies veranschaulicht, finden Sie unter Erwartete Ausnahmen.

Das folgende Codebeispiel veranschaulicht die Behandlung von SOAP-Fehlerausnahmen in einer grundlegenden Clientanwendung einschließlich eines deklarierten Fehlers und eines undeklarierten Fehlers.

ms732013.note(de-de,VS.100).gifHinweis:
Dieser Beispielcode verwendet kein using-Konstrukt. Da das Schließen von Kanälen Ausnahmen auslösen kann, ist es empfehlenswert, dass Anwendungen zuerst einen WCF-Client erstellen und dann den WCF-Client im selben try-Block öffnen, verwenden und schließen. Ausführliche Informationen finden Sie unter Übersicht über den WCF-Client und Vermeiden von Problemen mit der Using-Anweisung.

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 auch

Aufgaben

Erwartete Ausnahmen
Vermeiden von Problemen mit der Using-Anweisung

Verweis

FaultException
FaultException
System.ServiceModel.CommunicationException