定義並指定錯誤

SOAP 錯誤會將錯誤狀況資訊從服務傳送到用戶端,而在雙工案例中,則是以互通的方式從用戶端傳送到服務。 本主題討論何時及如何定義自訂錯誤內容,並指定可以傳回它們的作業。 如需服務或雙工用戶端如何傳送這些錯誤,以及用戶端或服務應用程式如何處理這些錯誤的詳細資訊,請參閱傳送和接收錯誤。 如需 Windows Communication Foundation (WCF) 應用程式中處理錯誤的概觀,請參閱指定及處理合約和服務中的錯誤

概觀

已宣告的 SOAP 錯誤是其中作業具有指定自訂 SOAP 錯誤類型之 System.ServiceModel.FaultContractAttribute的 SOAP 錯誤。 未宣告的 SOAP 錯誤則是在作業的合約中未指定的 SOAP 錯誤。 本主題將協助您識別這些錯誤狀況,並為您的服務建立錯誤合約,讓用戶端在收到自訂 SOAP 錯誤的通知時,可以用於正確處理這些錯誤狀況。 基本的工作依序為:

  1. 定義您服務的用戶端應該知道的錯誤狀況。

  2. 定義這些錯誤狀況的 SOAP 錯誤的自訂內容。

  3. 標示您的作業,讓其擲回的特定 SOAP 錯誤以 WSDL 格式對用戶端公開。

定義用戶端應知道的錯誤狀況

SOAP 錯誤是公開描述的訊息,具有特定作業的錯誤資訊。 由於它們是和其他作業訊息一起以 WSDL 描述的,因此用戶端知道並預期在叫用作業時處理這類錯誤。 但是由於 WCF 服務是以受控程式碼撰寫的,因此決定要將哪些使用受控程式碼的錯誤狀況轉換成錯誤並傳回用戶端,可讓您有機會將錯誤狀況和您服務中的錯誤與您和用戶端的正式錯誤對話分開。

例如,下列程式碼範例顯示採用兩個整數並傳回另一個整數的作業。 此處可擲回數個例外狀況,因此當設計錯誤合約時,您必須決定哪些錯誤狀況對您的用戶端是重要的。 在此案例中,服務應會偵測到 System.DivideByZeroException 例外狀況。

[ServiceContract]  
public class CalculatorService  
{  
    [OperationContract]
    int Divide(int a, int b)  
    {  
      if (b==0) throw new Exception("Division by zero!");  
      return a/b;  
    }  
}  
<ServiceContract> _
Public Class CalculatorService
    <OperationContract> _
    Public Function Divide(a As Integer, b As Integer) As Integer
        If b = 0 Then Throw New DivideByZeroException("Division by zero!")
        Return a / b
    End Function
End Class

在前例中,作業可以傳回除以零特定的自訂 SOAP 錯誤、數學作業特定但包含除以零特定的資訊的自訂錯誤、數個不同錯誤情況的多重錯誤或完全沒有 SOAP 錯誤。

定義錯誤狀況的內容

在錯誤狀況被識別為可用於傳回自訂 SOAP 錯誤之後,下一個步驟就是定義該錯誤的內容,並確保可以序列化內容結構。 上節的程式碼範例顯示 Divide 作業特定的錯誤,但如果 Calculator 服務上有其他的作業,則單一自訂 SOAP 錯誤可以通知用戶端所有的計算機錯誤狀況,包括 Divide。 下列程式碼範例顯示自訂 SOAP 錯誤 MathFault 的建立,它可以報告使用所有數學作業所造成的錯誤,包括 Divide。 雖然此類別可以指定作業 (Operation 屬性) 和描述問題的值 (ProblemType 屬性),但是此類別和這些屬性必須是可序列化的,才能傳輸到自訂 SOAP 錯誤中的用戶端。 因此,System.Runtime.Serialization.DataContractAttributeSystem.Runtime.Serialization.DataMemberAttribute 屬性是用於讓類型和其屬性變成可序列化的,並盡量互通。

// Define a math fault data contract
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public class MathFault
{
    private string operation;
    private string problemType;

    [DataMember]
    public string Operation
    {
        get { return operation; }
        set { operation = value; }
    }

    [DataMember]
    public string ProblemType
    {
        get { return problemType; }
        set { problemType = value; }
    }
}
' Define a math fault data contract
<DataContract([Namespace]:="http://Microsoft.ServiceModel.Samples")> _
Public Class MathFault

    Private m_operation As String
    Private m_problemType As String

    <DataMember()> _
    Public Property Operation() As String

        Get

            Return m_operation

        End Get

        Set(ByVal value As String)

            m_operation = value

        End Set

    End Property

    <DataMember()> _
    Public Property ProblemType() As String

        Get

            Return m_problemType

        End Get

        Set(ByVal value As String)

            m_problemType = value

        End Set

    End Property

End Class

如需有關如何確保資料可序列化的詳細資訊,請參閱在服務合約中指定資料傳輸。 如需 System.Runtime.Serialization.DataContractSerializer 提供的序列化支援清單,請參閱資料合約序列化程式支援的型別

標示作業以建立錯誤合約

在定義傳回做為自訂 SOAP 錯誤一部分的可序列化資料之後,最後一個步驟就是將您的作業合約標示為擲回該類型的 SOAP 錯誤。 如果要執行這項操作,請使用 System.ServiceModel.FaultContractAttribute 屬性,並傳遞您所建構之自訂資料型別的型別。 下列程式碼範例將示範如何使用 FaultContractAttribute 屬性來指定 Divide 作業可以傳回型別 MathFault 的 SOAP 錯誤。 其他以數學為基礎的作業現在也可以指定它們可以傳回 MathFault

[OperationContract]
[FaultContract(typeof(MathFault))]
int Divide(int n1, int n2);
<OperationContract()> _
<FaultContract(GetType(MathFault))> _
Function Divide(ByVal n1 As Integer, ByVal n2 As Integer) As Integer

作業可以使用一個以上的 FaultContractAttribute 屬性來標示該作業,以指定傳回一個以上的自訂錯誤。

下一步是要在您的作業實作中實作錯誤合約,在主題傳送和接收錯誤中將會說明。

SOAP、WSDL 和互通性考量

在某些情況中,特別是在與其他平台互通時,控制錯誤在 SOAP 訊息中出現的方式或在 WSDL 中繼資料中描述的方式可能會很重要。

FaultContractAttribute 屬性具有 Name 屬性,可控制為該錯誤在中繼資料中產生的 WSDL 錯誤項目名稱。

根據 SOAP 標準,錯誤可以有 ActionCodeReasonAction 是由 Action 屬性控制的。 Code 屬性和 Reason 屬性都是 System.ServiceModel.FaultException 類別的屬性,而該類別是一般 System.ServiceModel.FaultException<TDetail> 的父類別。 Code 屬性包括 SubCode 成員。

當存取產生錯誤的非服務時,會有特定限制。 WCF 只支援有結構描述所描述以及與資料合約相容之詳細型別的錯誤。 例如,如上所述,WCF 不支援在其詳細型別中使用 XML 屬性的錯誤,或在詳細資訊區段中有一個以上之最上層項目的錯誤。

另請參閱