Wcf 服务操作中的SOAP故障与返回代码

Wcf 服务操作中的SOAP故障与返回代码,wcf,Wcf,假设我正在设计一个与此类似的服务接口: [DataContract] public class MakePaymentRequest { [DataMember] public string AccountID { get; set; } [DataMember] public decimal PaymentAmount { get; set; } } [DataContract] public clas

假设我正在设计一个与此类似的服务接口:

[DataContract]
public class MakePaymentRequest
{    
    [DataMember]
    public string AccountID { get; set; }        

    [DataMember]
    public decimal PaymentAmount { get; set; }                
}

[DataContract]
public class MakePaymentResponse
{
    [DataMember]
    public string ConfirmationID { get; set; }

    [DataMember]
    public string ReceiptText { get; set; }        
}

[OperationContract]
MakePaymentResponse MakePayment(MakePaymentRequest makePaymentRequest);
有两种方法可以处理异常

1)使用返回码

在响应中包含返回代码

    [DataMember]
    public string ReturnCode { get; set; }
所以返回代码“000”表示成功等等。这种方法的缺点是,我需要在操作方法中使用try-catch:

public MakePaymentResponse MakePayment(MakePaymentRequest makePaymentRequest)
{
    try
    {
       // do stuff and return MakePaymentResponse with success code           
    }
    catch (Exception ex)
    {
       return new MakePaymentResponse { ReturnCode = "999" );
    } 
}
2)使用WCF全局异常处理并返回SOAP错误

将全局处理程序添加到自定义服务行为中:

public class FaultErrorHandler : IErrorHandler
{
   // ...
   public bool HandleError(Exception error)
    {
        try
        {
            _log.Error("Exception was caught", error);
        }
        catch { }
        return false;
    }

    public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
    {   
        if (fault == null)
        {
            FaultCode faultCode;
            if (error is ConfigurationErrorsException)
            { 
                faultCode = new FaultCode("Configuration");
            }
            else
            {
                faultCode = new FaultCode("Server error");
            }

            var fe = new FaultException<ReceiverFaultDetail>(new ReceiverFaultDetail("Unexpected error has occured", true), "Exception",  FaultCode.CreateReceiverFaultCode(faultCode));
            MessageFault mf = fe.CreateMessageFault();
            fault = Message.CreateMessage(version, mf, fe.Action);
        }            
    }
}
public类FaultErrorHandler:IErrorHandler
{
// ...
公共布尔句柄错误(异常错误)
{
尝试
{
_log.Error(“捕获异常”,Error);
}
捕获{}
返回false;
}
公共默认值(异常错误,System.ServiceModel.Channels.MessageVersion版本,参考System.ServiceModel.Channels.Message故障)
{   
if(fault==null)
{
故障码故障码;
if(错误为配置错误异常)
{ 
faultCode=新的faultCode(“配置”);
}
其他的
{
faultCode=新的故障代码(“服务器错误”);
}
var fe=新的FaultException(新的ReceiverFaultDetail(“发生了意外错误”,true),“异常”,FaultCode.CreateReceiverFaultCode(FaultCode));
MessageFault mf=fe.CreateMessageFault();
故障=Message.CreateMessage(版本、mf、fe.Action);
}            
}
}

我更喜欢第二种方案,因为它更干净,不会对频道造成故障,但我想知道,在这条路线上我是否遗漏了什么。

实际上,我建议两者都使用。您应该在服务代码中实现正常异常处理(try-catch),并使用全局错误处理程序来捕获未捕获的异常。为什么两者都要捕获?调用方在每次操作后检查返回代码有什么好处?若服务器发送SOAP错误,将出现FaultException(至少在.Net平台上)。