在WCF中,如果没有指定,服务端的异常不会传递到客户端,如:在等于0时,客户端根本不知道异常的原因据,也即"Divsion by zero!"异常信息不会传到客户端。
[ServiceContract]
public class CalculatorService
... {
[OperationContract]
int Divide(int a, int b)
...{
if (b==0) throw new Exception(“Division by zero!”);
return a/b;
}
}
public class CalculatorService
... {
[OperationContract]
int Divide(int a, int b)
...{
if (b==0) throw new Exception(“Division by zero!”);
return a/b;
}
}
在最简单的情况下,我们可以使用空FaultException(它只包含一个string字符串,称为错误原因), 如下所示:
[ServiceContract]
public class CalculatorService
... {
[OperationContract]
int Divide(int a, int b)
...{
if (b==0) throw new FaultException(“Division by zero!”);
return a/b;
}
}
public class CalculatorService
... {
[OperationContract]
int Divide(int a, int b)
...{
if (b==0) throw new FaultException(“Division by zero!”);
return a/b;
}
}
当然,我们可以定义强类型的异常信息,并在方法上运用FaultContractAttribute来指定它,如下所示:
[DataContract]
public class MathFault
... {
[DataMember]
public string operation;
[DataMember]
public string description;
}
[ServiceContract]
public class CalculatorService
... {
[FaultContract(typeof(MathFault))]
[OperationContract]
int Divide(int a, int b)
...{
if (b==0)
...{
MathFault m = new MathFault();
m.operation=”/”;
m.description=”Division by zero!”;
throw new FaultException<MathFault>(m);
}
return a/b;
}
}
public class MathFault
... {
[DataMember]
public string operation;
[DataMember]
public string description;
}
[ServiceContract]
public class CalculatorService
... {
[FaultContract(typeof(MathFault))]
[OperationContract]
int Divide(int a, int b)
...{
if (b==0)
...{
MathFault m = new MathFault();
m.operation=”/”;
m.description=”Division by zero!”;
throw new FaultException<MathFault>(m);
}
return a/b;
}
}
注意:不能用XmlSerializer来序列化Fault相关的对象实例,即使在其上使用了XmlSerializerFormatAttribute属性。
为了调试目的,可以用ReturnUnknownExceptionsAsFaults配置项(配置文件)或是在服务上使用ServiceBehaviorAttribute 属性来将所有异常作为Fault返回给客户端, 如下所示:
[ServiceContract]
[ServiceBehavior(ReturnUnknownExceptionsAsFaults = true )]
public class CalculatorService
... {
[OperationContract] int Divide(int a, int b)
...{
return a/b; // This may throw the DivideByZeroException.
}
}
[ServiceBehavior(ReturnUnknownExceptionsAsFaults = true )]
public class CalculatorService
... {
[OperationContract] int Divide(int a, int b)
...{
return a/b; // This may throw the DivideByZeroException.
}
}