SOAP 錯誤會以兼容的方式將錯誤資訊從服務傳遞至用戶端,在雙工情況下,錯誤資訊也會從用戶端傳送到服務。 本主題討論何時及如何定義自定義錯誤內容,並指定哪些作業可以傳回它們。 如需服務或雙工用戶端如何傳送這些錯誤,以及用戶端或服務應用程式如何處理這些錯誤的詳細資訊,請參閱 傳送和接收錯誤。 如需 Windows Communication Foundation (WCF) 應用程式中錯誤處理的概觀,請參閱 指定及處理合約和服務中的錯誤。
概觀
宣告的 SOAP 錯誤是指某個作業含有 System.ServiceModel.FaultContractAttribute,指定了一種自訂的 SOAP 錯誤類型。 未宣告的 SOAP 錯誤是作業合約中未指定的錯誤。 本主題可協助您識別這些錯誤狀況,併為服務建立錯誤合約,讓用戶端可在自定義SOAP錯誤收到通知時,用來正確處理這些錯誤狀況。 基本工作順序如下:
定義服務客戶端應該知道的錯誤狀況。
針對這些錯誤狀況定義 SOAP 錯誤的自訂內容。
標記您的作業,以便透過 WSDL 將特定 SOAP 錯誤公開給用戶端。
定義客戶端應該知道的錯誤狀況
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.DataContractAttribute 和 System.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 作業可以傳回 SOAP錯誤的MathFault類型。 其他以數學為基礎的運算現在也可以指定它們可以傳回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 標準,錯誤可以有 Action、 Code和 Reason。
Action由 Action 屬性控制。 屬性 Code 和 Reason 都是類別 System.ServiceModel.FaultException 的屬性,System.ServiceModel.FaultException 是泛型 的父類別。 屬性 Code 包含 SubCode 成員。
存取產生錯誤的非服務時,存在某些限制。 WCF 僅支援架構所描述的詳細資料類型,且與數據合約相容的故障。 例如,如上所述,WCF 不支援在詳細數據類型中使用 XML 屬性的錯誤,或詳細數據區段中有多個最上層元素的錯誤。