1、WCF基本异常处理模式
1)、在默认的情况下,客户端是不可以捕捉到服务端抛出的异常错误信息,我们可以通过配置和代码的方式打开调试信息,让客户端获取到服务端抛出的异常:
- 配置方式:
<behaviors>
<serviceBehaviors>
<behaviors name ="serviceDebugBehaviors">
<seviceDebug includeExceptionDetailInFaults="true"/>
</behaviors>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration ="serviceDebugBehaviors" .....>
</services>
- 代码方式:在相应的服务上添加ServiceBehavior特性,配置IncludeExceptionDetailInFaults属性为True即可。
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class CalculatorServices:ICalculator
{}
尽管可以通过两种方式,可以让客户获取到服务端抛出的异常,但是,这样的话,服务端所有的异常都会明明白白的展现在客户端,在某些情况下还是不安全的,那么我们如何自定义错误信息呢,也就是如何选择性的抛出服务端的异常错误信息呢,就是下面讲的错误契约的作用。
2)、错误契约:
在服务端我们通常通过FaultException<TDetail>泛型类型包装我们自定义的错误信息,下面举个例子说明如何使用错误契约:
- 首先定义一个自定义的异常数据类型:
[DataContract(Namespace=http://www.hanshuai.com)]
public class CalculationError
{
public CalculationError(string operation,string message)
{
this.Operation=operation;
this.Message=message;
}
[DataMember]
public string Operation{get;set;}
[DataMember]
public string Message{get;set;}
}
- 在服务契约中:
[ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]//指定错误契约类型CalculationError
int Divide(int x,int y);
}
- 在服务实现的时候:
public class CalculatorService:ICalculator
{
public int Divide(int x,int y)
{
if(0==y)//被除数为0
{
var error =new CalculationError("Divide","被除数y不能为0");
throw new FaultException<CalculationError>(error,error.Message);//抛出异常
}
return x / y;
}
}
这样,当我们在客户端调用Divide方法的时候,如果y为0,就会抛出“被除数y不能为0”的错误信息。
try
{
int result =calculator.Divide(1,0);
}
catch(FaultException<CalculationError> ex)
{
ex.Detail.Operation;//服务端自定义的错误操作
ex.Detail.Message;
}
到此,基本可以了解到,如何在服务端自定义错误信息,但是,对于错误契约,有几个特别的细节需要注意下:
- 在服务契约中,一个操作方法上可以多个错误契约,如:
[FaultContract(typeof(CalculationError)]
[FaultContract(typeof(string)]
int Divide(int x, int y);
但是,多个错误契约的错误类型不可以相同,如果相同,必须通过name属性,指定不同的名称,另外,不同的错误类型,应用在同一个草错方法上,不可以指定相同的name和namespace 如下页是不允许的:
[FaultContract(typeof(CalculationError),name ="Fault",namespace ="http://www.hanshuai.com"]
[FaultContract(typeof(string),name ="Fault",namespace ="http://www.hanshuai.com"]
int Divide(int x, int y);
浙公网安备 33010602011771号