預設情況下服務端異常不傳遞至客戶端,開啟 IncludeExceptionDetailInFaults 則全暴露。生產環境需折中方案:自定義錯誤資訊,兼顧可理解性與資訊安全。
服務操作中直接 throw new FaultException("被除數y不能為零!"),客戶端捕獲 FaultException 即可獲取自訂訊息。但更推薦使用強型別錯誤明細。
定義資料契約 CalculationError(含 Operation、Message 成員)。服務端拋出 FaultException<CalculationError>,客戶端捕獲 FaultException<CalculationError> 存取 Detail 屬性。但若缺少契約聲明,客戶端會收到基底 FaultException 而非泛型型別。
SOA 核心在於契約。服務契約定義正常調用訊息結構,錯誤契約定義 Fault 訊息結構。WCF 透過 FaultContractAttribute 在操作契約上聲明:
[AttributeUsage(AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public sealed class FaultContractAttribute : Attribute
{
public FaultContractAttribute(Type detailType);
public string Action { get; set; }
public Type DetailType { get; }
public string Name { get; set; }
public string Namespace { get; set; }
public ProtectionLevel ProtectionLevel { get; set; }
}
屬性含義:Action 控制 WS-Addressing Action 報頭(預設規則:{契約NS}/{契約名}/{操作名}{明細型別名}Fault);DetailType 指定錯誤明細型別;Name/Namespace 控制序列化後 XML 的 QName(預設用資料契約名稱);保護層級屬性涉及安全。
聲明後,服務端拋出對應 FaultException<TDetail>,WCF 生成 Fault 訊息,明細序列化置於 SOAP Detail。WSDL 中體現為 <wsdl:fault> 節點。基元型別(如 string)同樣需聲明 FaultContract(typeof(string))。