エラーの送受信Sending and Receiving Faults

SOAP エラーは、エラー状態情報をサービスからクライアントに伝達します。双方向通信の場合は、相互運用可能な方法でクライアントからサービスにも伝達します。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. 通常、サービスは、カスタムのエラー コンテンツを定義し、そのエラー コンテンツを返すことができる操作を指定します Typically a service defines custom fault content and specifies which operations can return them. (詳細については、次を参照してくださいの定義と指定するエラー。)。ここでは、対応するエラー状態が発生したときにサービスまたは双方向クライアントがエラーを送信する方法、およびクライアントまたはサービス アプリケーションがエラーを処理する方法について説明します。(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. Windows Communication Foundation (WCF) アプリケーションのエラー処理の概要については、次を参照してください。を指定すると処理のエラー コントラクトおよびサービスのします。For an overview of error handling in Windows Communication Foundation (WCF) applications, see Specifying and Handling Faults in Contracts and Services.

SOAP エラーの送信Sending SOAP Faults

宣言された SOAP エラーは、カスタム SOAP エラーの種類を指定する System.ServiceModel.FaultContractAttribute を含む操作で発生します。Declared SOAP faults are those in which an operation has a System.ServiceModel.FaultContractAttribute that specifies a custom SOAP fault type. 宣言されていない SOAP エラーとは、操作のコントラクトに指定されていないエラーです。Undeclared SOAP faults are those that are not specified in the contract for an operation.

宣言されたエラーの送信Sending Declared Faults

宣言された SOAP エラーを送信するには、SOAP エラーに該当するエラー状態を検出し、新しい System.ServiceModel.FaultException<TDetail> をスローします。この場合、型パラメーターは、その操作の FaultContractAttribute に指定されている型の新しいオブジェクトです。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. 次のコード例は、FaultContractAttribute 操作で SampleMethod の詳細な型と共に SOAP エラーを返すことができることを指定するために、GreetingFault を使用しています。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

GreetingFault エラー情報をクライアントに伝達するには、適切なエラー状態をキャッチし、次のコード例に示すように、新しい System.ServiceModel.FaultException<TDetail> オブジェクトを引数として使用して GreetingFault 型の新しい GreetingFault をスローします。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. これを型がマネージ例外として認識、クライアントが WCF クライアント アプリケーションの場合は、System.ServiceModel.FaultException<TDetail>型の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

宣言されていないエラーの送信Sending Undeclared Faults

宣言されていないエラーの送信元は速やかに診断してデバッグ ツールは、WCF のアプリケーションがその有用性の問題をデバッグすると便利にすることはできます。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. 一般的に、デバッグ時には ServiceDebugBehavior.IncludeExceptionDetailInFaults プロパティを使用することをお勧めします。More generally, when debugging it is recommended that you use the ServiceDebugBehavior.IncludeExceptionDetailInFaults property. この値を true に設定すると、クライアントはこのエラーを FaultException<TDetail> 型の ExceptionDetail 例外として認識します。When you set this value to true, clients experience such faults as FaultException<TDetail> exceptions of type ExceptionDetail.

重要

設定するため、マネージ例外には、内部アプリケーション情報を公開できますが、ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsまたはServiceDebugBehavior.IncludeExceptionDetailInFaultstrue個人など、内部サービス操作例外に関する情報を取得する WCF クライアントを許可します。特定できる情報やその他の機密情報。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.

したがって、ServiceBehaviorAttribute.IncludeExceptionDetailInFaults または ServiceDebugBehavior.IncludeExceptionDetailInFaultstrue に設定することは、サービス アプリケーションを一時的にデバッグする方法としてのみお勧めできます。Therefore, setting ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or ServiceDebugBehavior.IncludeExceptionDetailInFaults to true is only recommended as a way of temporarily debugging a service application. さらに、このようにして未処理のマネージド例外を返すメソッドの WSDL には、FaultException<TDetail> 型の 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. クライアントは、不明な SOAP エラーの可能性を想定する必要があります (として WCF クライアントに返されるSystem.ServiceModel.FaultExceptionオブジェクト) を正しくデバッグ情報を取得します。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.

宣言されていない SOAP エラーを送信するには、System.ServiceModel.FaultException (つまり、ジェネリック型の FaultException<TDetail> でない) オブジェクトをスローし、文字列をコンストラクターに渡します。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. これは、スローされたとして WCF クライアント アプリケーションに公開System.ServiceModel.FaultException例外の文字列が使用可能な呼び出すことによって、FaultException<TDetail>.ToStringメソッド。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.

注意

文字列型の SOAP エラーを宣言し、これを型パラメーターが FaultException<TDetail>System.String としてサービス内でスローすると、文字列値が FaultException<TDetail>.Detail プロパティに割り当てられるため、FaultException<TDetail>.ToString から使用できません。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.

エラーの処理Handling Faults

WCF クライアントではマネージ例外としてクライアント アプリケーションに関心のある通信中に発生した SOAP エラーが発生します。In WCF clients, SOAP faults that occur during communication that are of interest to client applications are raised as managed exceptions. 任意のプログラムの実行中に発生することが多くの例外はありますが、通信の結果として次の 2 種類の例外を処理するために、WCF クライアントのプログラミング モデルを使用してアプリケーションが期待できます。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 オブジェクトは、操作が、指定されたタイムアウト期間を超えた場合にスローされます。TimeoutException objects are thrown when an operation exceeds the specified timeout period.

CommunicationException オブジェクトは、回復可能な通信エラー状態がサービスまたはクライアントで発生した場合にスローされます。CommunicationException objects are thrown when there is some recoverable communication error condition on either the service or the client.

CommunicationException クラスには、FaultException および一般的な FaultException<TDetail> 型という 2 つの重要な派生型があります。The CommunicationException class has two important derived types, FaultException and the generic FaultException<TDetail> type.

FaultException 例外は、予期しないエラーまたは操作コントラクト内に指定されていないエラーをリスナーが受信した場合にスローされます。この例外は、通常、サービスの ServiceDebugBehavior.IncludeExceptionDetailInFaults プロパティを true に設定してアプリケーションをデバッグしている場合に発生します。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.

FaultException<TDetail> 例外は、操作コントラクト内に指定されたエラーが、双方向操作 (つまり、OperationContractAttributeIsOneWay が設定されている false 属性を持つメソッド) への応答で受信された場合に、クライアントでスローされます。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).

注意

WCF サービスは、発生した場合、ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsまたはServiceDebugBehavior.IncludeExceptionDetailInFaultsプロパティに設定trueとして宣言されていないは、クライアントでこのFaultException<TDetail>型の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. クライアントは、この特定のエラーをキャッチするか、FaultException の catch ブロックで処理できます。Clients can either catch this specific fault or handle the fault in a catch block for FaultException.

通常、クライアントとサービスには、FaultException<TDetail>TimeoutException、および CommunicationException の各例外だけが関係します。Typically, only FaultException<TDetail>, TimeoutException, and CommunicationException exceptions are of interest to clients and services.

注意

上記以外の例外も発生します。Other exceptions, of course, do occur. 予期しない例外には System.OutOfMemoryException のような致命的なエラーも含まれますが、通常、アプリケーションでは、このようなメソッドをキャッチしません。Unexpected exceptions include catastrophic failures like System.OutOfMemoryException; typically applications should not catch such methods.

正しい順序でエラー例外をキャッチするCatch Fault Exceptions in the Correct Order

FaultException<TDetail>FaultException から派生します。また、FaultExceptionCommunicationException からも派生します。したがって、これらの例外を正しい順序でキャッチすることが重要になります。Because FaultException<TDetail> derives from FaultException, and FaultException derives from CommunicationException, it is important to catch these exceptions in the proper order. たとえば、try/catch ブロックで最初に CommunicationException がキャッチされたとします。その場合、すべての SOAP エラー (指定されている SOAP エラーおよび指定されていない SOAP エラー) はそこで処理され、カスタムの FaultException<TDetail> 例外を処理する後続の catch ブロックは呼び出されません。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.

指定した例外が 1 つの操作から複数返される場合があることに注意してください。Remember that one operation can return any number of specified faults. その場合は、エラーごとに型が異なるため、個別に処理する必要があります。Each fault is a unique type and must be handled separately.

チャネルを閉じるときに例外を処理するHandle Exceptions When Closing the Channel

これまでの説明のほとんどは、クライアント アプリケーションの WCF クライアント オブジェクトの操作を呼び出すときに、クライアントによって明示的に送信されたメッセージは、アプリケーション メッセージの処理の過程で送信されるエラーにいます。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.

ローカル オブジェクトでも、オブジェクトを破棄すると、リサイクル プロセスで起こる例外が発生したり、マスクされたりする場合があります。Even with local objects disposing the object can either raise or mask exceptions that occur during the recycling process. 以下のように WCF クライアント オブジェクトを使用すると発生します。Something similar can occur when you use WCF client objects. 操作を呼び出すと、既に確立されている接続を通じてメッセージが送信されます。When you call operations you are sending messages over an established connection. また、チャネルを閉じると、すべての操作が正常に返されたとしても、接続を完全に閉じることができなかったり、接続が既に閉じたりしている場合には、例外がスローされる可能性があります。Closing the channel can throw exceptions if the connection cannot be cleanly closed or is already closed, even if all the operations returned properly.

通常、クライアント オブジェクトのチャネルは、次のいずれかが発生すると閉じられます。Typically, client object channels are closed in one of the following ways:

  • WCF クライアント オブジェクトがリサイクルされる場合です。When the WCF client object is recycled.

  • クライアント アプリケーションが ClientBase<TChannel>.Close を呼び出すとき。When the client application calls ClientBase<TChannel>.Close.

  • クライアント アプリケーションが ICommunicationObject.Close を呼び出すとき。When the client application calls ICommunicationObject.Close.

  • クライアント アプリケーションが、セッションの終了操作となる操作を呼び出すとき。When the client application calls an operation that is a terminating operation for a session.

いずれの場合でも、チャネルを閉じると、アプリケーション レベルで複雑な機能をサポートするためにメッセージを送信している可能性がある基になるチャネルをすべて閉じる操作を開始するように、チャネルに通知されます。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. たとえば、コントラクトがセッションを要求している場合、バインディングは、セッションが確立されるまでサービス チャネルとメッセージを交換してセッションを確立しようとします。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. チャネルが閉じられると、基になるセッション チャネルは、セッションが終了したことをサービスに通知します。When the channel is closed, the underlying session channel notifies the service that the session is terminated. この場合、チャネルが既に中止されたり閉じられたりしている、または使用できない (たとえば、ネットワーク ケーブルが外れている) ときには、クライアント チャネルはサービス チャネルに対し、セッションが終了し例外が発生する可能性があることを通知できません。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.

必要に応じてチャネルを中止するAbort the Channel If Necessary

チャネルを閉じると例外がスローされる可能性があるため、正しい順序でエラー状態をキャッチするだけでなく、呼び出しに使用されたチャネルを catch ブロックで中止することが重要です。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.

エラーによって操作に固有のエラー情報が伝えられた場合、他のユーザーがそのエラー情報を使用できるときはチャネルを中止する必要はありません (ただし、このような状況は非常にまれです)。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 all other cases, it is recommended that you abort the channel. これらのポイントをすべて示すサンプルでは、次を参照してください。予想例外します。For a sample that demonstrates all of these points, see Expected Exceptions.

次のコード例は、基本的なクライアント アプリケーションで、宣言されたエラーと宣言されていないエラーを含む SOAP エラー例外を処理する方法を示しています。The following code example shows how to handle SOAP fault exceptions in a basic client application, including a declared fault and an undeclared fault.

注意

このサンプル コードは、using コンストラクトを使用していません。This sample code does not use the using construct. チャネルを閉じると、例外をスローできます、ために、アプリケーションが WCF のクライアント、し、オープンであり、最初の使用を作成し、WCF でクライアントに同じ try ブロックで閉じることをお勧めします。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. 詳細については、次を参照してください。 WCF Client Overview使用終了、中止 WCF クライアントのリソースを解放するします。For details, see WCF Client Overview and Use Close and Abort to release WCF client resources.

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

関連項目See also