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平台上)。