FaultContractAttribute 類別

定義

指定一個或多個 SOAP 錯誤,當服務作業遇到處理錯誤時會傳回這些 SOAP 錯誤。

public ref class FaultContractAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public sealed class FaultContractAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)>]
type FaultContractAttribute = class
    inherit Attribute
Public NotInheritable Class FaultContractAttribute
Inherits Attribute
繼承
FaultContractAttribute
屬性

範例

下列程式碼範例將示範如何使用 FaultContractAttribute 來指定 SampleMethod 作業可以傳回 SOAP 錯誤,連同 GreetingFault 的詳細型別。

using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Microsoft.WCF.Documentation
{
  [ServiceContract(Namespace="http://microsoft.wcf.documentation")]
  public interface ISampleService{
    [OperationContract]
    [FaultContractAttribute(
      typeof(GreetingFault),
      Action="http://www.contoso.com/GreetingFault",
      ProtectionLevel=ProtectionLevel.EncryptAndSign
      )]
    string SampleMethod(string msg);
  }

  [DataContractAttribute]
  public class GreetingFault
  {
    private string report;

    public GreetingFault(string message)
    {
      this.report = message;
    }

    [DataMemberAttribute]
    public string Message
    {
      get { return this.report; }
      set { this.report = value; }
    }
  }

  class SampleService : ISampleService
  {
  #region ISampleService Members

  public string  SampleMethod(string msg)
  {
    Console.WriteLine("Client said: " + msg);
    // Generate intermittent error behavior.
    Random rnd = new Random(DateTime.Now.Millisecond);
    int test = rnd.Next(5);
    if (test % 2 != 0)
      return "The service greets you: " + msg;
    else
      throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg));
  }

  #endregion
  }
}

Imports System.Collections.Generic
Imports System.Net.Security
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.Text

Namespace Microsoft.WCF.Documentation
  <ServiceContract(Namespace:="http://microsoft.wcf.documentation")> _
  Public Interface ISampleService
    <OperationContract, FaultContractAttribute(GetType(GreetingFault), Action:="http://www.contoso.com/GreetingFault", ProtectionLevel:=ProtectionLevel.EncryptAndSign)> _
    Function SampleMethod(ByVal msg As String) As String
  End Interface

  <DataContractAttribute> _
  Public Class GreetingFault
    Private report As String

    Public Sub New(ByVal message As String)
      Me.report = message
    End Sub

    <DataMemberAttribute> _
    Public Property Message() As String
      Get
          Return Me.report
      End Get
      Set(ByVal value As String)
          Me.report = value
      End Set
    End Property
  End Class

  Friend Class SampleService
      Implements ISampleService
  #Region "ISampleService Members"

  Public Function SampleMethod(ByVal msg As String) As String Implements ISampleService.SampleMethod
    Console.WriteLine("Client said: " & msg)
    ' Generate intermittent error behavior.
    Dim rand As New Random(DateTime.Now.Millisecond)
    Dim test As Integer = rand.Next(5)
    If test Mod 2 <> 0 Then
      Return "The service greets you: " & msg
    Else
      Throw New FaultException(Of GreetingFault)(New GreetingFault("A Greeting error occurred. You said: " & msg))
    End If
  End Function

  #End Region
  End Class
End Namespace

下列程式碼範例顯示 WCF 用戶端 ISampleService 在 類型 GreetingFaultFaultException<TDetail> 遇到這個 SOAP 錯誤。

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

備註

使用 屬性標記作業, FaultContractAttribute 以宣告新增至 Web 服務描述語言的一或多個特定例外狀況, (WSDL) 服務作業的描述,作為作業所傳回的明確 SOAP 錯誤訊息。

在所有 Managed 應用程式中,處理錯誤由 Exception 物件表示。 在以 SOAP 為基礎的應用程式中,例如 Windows Communication Foundation (WCF) 應用程式,服務方法會使用 SOAP 錯誤訊息來通訊處理錯誤資訊。 因為 WCF 應用程式會在這兩種類型的錯誤系統下執行,所以必須傳送至用戶端的任何 Managed 例外狀況資訊都必須從例外狀況轉換成 SOAP 錯誤。 您可使用預設的服務例外狀況行為,或自行控制是否要將例外狀況對應到錯誤訊息,以及其對應方式。 如需 WCF 應用程式中例外狀況和 SOAP 錯誤的概觀,請參閱 在合約和服務中指定和處理錯誤

建議服務作業使用 FaultContractAttribute 來正式指定用戶端預期在作業正常過程中接收的所有 SOAP 錯誤。 我們也建議 SOAP 錯誤只傳回用戶端應該知道的資訊,將資訊暴露的程度降至最低。

  • 屬性 Action 會控制錯誤訊息的動作。

  • 屬性 DetailType 會取得在錯誤訊息中序列化的詳細資料物件類型。

  • NameNamespace 屬性分別控制錯誤訊息的名稱和命名空間。

  • HasProtectionLevel指出錯誤訊息是否已指定保護等級,如果是, ProtectionLevel 則屬性會控制該層級的保護。

警告

如果錯誤訊息含有敏感性或可能導致安全性問題的資訊,強烈建議 ProtectionLevel 設定 屬性。

對於許多針對錯誤訊息設定 ProtectionLevelEncryptAndSign 的案例,就已足夠。 如需詳細資訊,請參閱 瞭解保護層級

若要從標示 FaultContractAttribute 為 的作業傳回指定的錯誤,請擲 FaultException<TDetail> 回 (,其中 type 參數是作業期間發生 Managed 例外狀況時的可序列化錯誤資訊) 。 WCF 用戶端應用程式會顯示 SOAP 錯誤,如同在用戶端實作中擲回的相同類型,亦即, FaultException<TDetail> (,其中 typeparameter 是可序列化的錯誤資訊) 。 FaultContractAttribute只能用來指定雙向服務作業和非同步作業配對的 SOAP 錯誤;單向作業不支援 SOAP 錯誤,因此不支援 FaultContractAttribute

注意

您可使用任何可序列化型別來傳遞錯誤資訊。 這個 WCF 版本的唯一限制是 中指定的 FaultContractAttribute 型別必須由 序列化 System.Runtime.Serialization.DataContractSerializer 。 如需提供的序列化支援 DataContractSerializer ,請參閱 資料合約序列化程式

例如,若要指定用戶端可以預期包含 Int32 的 SOAP 錯誤,請將該類型參數放在 FaultContractAttribute 您的服務方法上。

注意

下列程式碼範例不會設定 ProtectionLevelNameNamespace 屬性。

[OperationContractAttribute]
[FaultContractAttribute(typeof(int))]
int Divide(int arg1, int arg2);
  <OperationContractAttribute(), FaultContractAttribute(GetType(Integer))> _
    Function Divide(ByVal arg1 As Integer, ByVal arg2 As Integer) As Integer
End Interface 'FCADemonstration

然後,在您的服務方法中,擲回新的 FaultException<TDetail> ,其中 type 參數是類型,其中包含上述案例 Int32 中錯誤資訊 () 。 例如:

throw new FaultException<int>(4);
Throw New FaultException(Of Integer)(4)

上述範例非常基本;幾乎可以使用程式碼傳遞 System.Int32 任何資訊,因此此詳細資料類型並不是最有用的。 一般而言,WCF 應用程式會指定 SOAP 錯誤,其中包含用戶端錯誤資訊需求特有的詳細類型。 如需更完整的範例,請參閱<範例>一節。

注意

如果您指定 FaultException<TDetail> 類型參數為 System.String 的 ,則會將字串值指派給用戶端應用程式中的 Detail 屬性;用戶端無法藉由呼叫 FaultException<TDetail>.ToString 方法來擷取該字串。 若要在用戶端應用程式呼叫 Exception.ToString 時傳回字串值,請在該作業內擲回一個 System.ServiceModel.FaultException 例外狀況,並將字串傳遞給建構函式。

若要在擲回例外狀況或 FaultException<TDetail> 擲回時明確控制應用程式的行為,請在 上 System.ServiceModel.Description.IServiceBehaviorSystem.ServiceModel.Dispatcher.IErrorHandler 作 介面, System.ServiceModel.Description.IContractBehaviorSystem.ServiceModel.Description.IEndpointBehavior 並將它指派給 ChannelDispatcher.ErrorHandlers 屬性。 IErrorHandler 可讓您明確控制產生的 SOAP 錯誤,以及是否要將它傳回用戶端。

為了方便偵錯,請在程式碼中將 設定 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultstrue ,或者您可以在應用程式組態檔中使用 ServiceDebugBehavior.IncludeExceptionDetailInFaults 。 啟用時,服務會自動將例外狀況資訊傳回給呼叫者。 這些錯誤會顯示為例外狀況給用戶端 FaultException

重要

由於 Managed 例外狀況可以公開內部應用程式資訊,因此設定 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultstrue ServiceDebugBehavior.IncludeExceptionDetailInFaults 允許 WCF 用戶端取得內部服務作業例外狀況的相關資訊,包括個人標識或其他敏感性資訊。

因此,若您只是暫時對服務應用程式進行偵錯,才建議把 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsServiceDebugBehavior.IncludeExceptionDetailInFaults 設為 true。 此外,若某個方法以這種方式傳回未處理的 Managed 例外狀況,則該方法的 WSDL 不會包含 FaultException<TDetail> 型別之 String 的合約。 用戶端必須預期未知的 SOAP 錯誤 (傳回 WCF 用戶端的可能性,因為 System.ServiceModel.FaultException 物件) 才能正確取得偵錯資訊。

建構函式

FaultContractAttribute(Type)

初始化 FaultContractAttribute 類別的新執行個體。

屬性

Action

取得或設定 SOAP 錯誤訊息的動作,此訊息指定為作業合約的一部分。

DetailType

取得包含錯誤資訊的可序列化物件型別。

HasProtectionLevel

取得指出 SOAP 錯誤訊息是否已指派保護層級的值。

Name

取得或設定 Web 服務描述語言 (WSDL) 中的錯誤訊息名稱。

Namespace

取得或設定 SOAP 錯誤的命名空間。

ProtectionLevel

指定 SOAP 錯誤從繫結要求的保護層級。

TypeId

在衍生類別中實作時,取得這個 Attribute 的唯一識別碼。

(繼承來源 Attribute)

方法

Equals(Object)

傳回值,這個值指出此執行個體是否與指定的物件相等。

(繼承來源 Attribute)
GetHashCode()

傳回這個執行個體的雜湊碼。

(繼承來源 Attribute)
GetType()

取得目前執行個體的 Type

(繼承來源 Object)
IsDefaultAttribute()

在衍生類別中覆寫時,表示這個執行個體的值是衍生類別的預設值。

(繼承來源 Attribute)
Match(Object)

在衍生類別中覆寫時,會傳回值,表示這個執行個體是否等於指定物件。

(繼承來源 Attribute)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
ToString()

傳回代表目前物件的字串。

(繼承來源 Object)

明確介面實作

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

將一組名稱對應至一組對應的分派識別項 (Dispatch Identifier)。

(繼承來源 Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

擷取物件的類型資訊,可以用來取得介面的類型資訊。

(繼承來源 Attribute)
_Attribute.GetTypeInfoCount(UInt32)

擷取物件提供的類型資訊介面數目 (0 或 1)。

(繼承來源 Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供物件所公開的屬性和方法的存取權。

(繼承來源 Attribute)

適用於