Welcome

首页 / 软件开发 / WCF / WCF技术剖析之二十一:WCF基本异常处理模式[下篇]

WCF技术剖析之二十一:WCF基本异常处理模式[下篇]2012-11-14 博客园 Artech从FaultContractAttribute的定义我们可以看出,该特性可以在同一个目标对象上面多次应用(AllowMultiple = true)。这也很好理解:对于同一个服务操作,可能具有不同的异常场景,在不同的情况下,需要抛出不同的异常。

 1: [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
2: public sealed class FaultContractAttribute : Attribute
3: {
4: //省略成员
5: }
但是,如果你在同一个操作方法上面应用了多了FaultContractAttribute特性的时候,需要遵循一系列的规则,我们现在就来逐条介绍它们。

一、多次声明相同的错误明细类型

比如在下面的代码中,对于操作Divide,通过FaultContractAttribute特性对同一个错误明细类型CalculationError进行了两次设置。

 1: using System.ServiceModel;
2: namespace Artech.WcfServices.Contracts
3: {
4: [ServiceContract(Namespace = "http://www.artech.com/")]
5: public interface ICalculator
6: {
7: [OperationContract]
8: [FaultContract(typeof(CalculationError))]
9: [FaultContract(typeof(CalculationError))]
10: int Divide(int x, int y);
11: }
12: }
WCF服务端框架在初始化ServiceHost,并创建服务表述的时候(关于服务描述,以及在服务寄宿过程中对服务描述的创建,《WCF技术剖析(卷1)》的第7章有详细的介绍),会抛出如图1所示的InvalidOperationException异常。

图1 多次声明相同的错误明细类型导致的异常

但是,如果你在应用FaultContractAttribute特性指定相同错误明细类型的同时,指定不同的Name或者Namespace,这是允许的。比如下面的代码中,在两个FaultContractAttribute特性中,同样是指定的相同的错误明细类型CalculationError,由于我们为之指定了不同的Name,在寄宿服务的时候将不会有上述异常的发生。

 1: using System.ServiceModel;
2: namespace Artech.WcfServices.Contracts
3: {
4: [ServiceContract(Namespace = "http://www.artech.com/")]
5: public interface ICalculator
6: {
7: [OperationContract]
8: [FaultContract(typeof(CalculationError), Name = "CalculationError")]
9: [FaultContract(typeof(CalculationError), Name = "CalculationException")]
10: int Divide(int x, int y);
11: }
12: }
二、多次声明不同的具有相同有效名称错误明细类型

多次声明的错误类型的类型虽然不同,但是如果我们为其指定相同的Name和Namespace我们可以将Name和Namespace的组合称为有效名称QN:Qualified Name),这依然是不允许的。比如下面的代码中,通过FaultContractAttribute特性为Divide操作指定了两个不同的错误明细类型(CalculationError和CalculationException),但是设置的名称却是相同的(CalculationError)。

 1: using System.ServiceModel;
2: namespace Artech.WcfServices.Contracts
3: {
4: [ServiceContract(Namespace = "http://www.artech.com/")]
5: public interface ICalculator
6: {
7: [OperationContract]
8: [FaultContract(typeof(CalculationError),
9: Name = "CalculationError", Namespace = "http://www.artech.com/")]
10: [FaultContract(typeof(CalculationException),
11: Name = "CalculationError", Namespace = "http://www.artech.com/")]
12: int Divide(int x, int y);
13: }
14: }
对于这种情况,在服务寄宿的时候,依然会和上面一样抛出一个InvalidOperationExcepiton异常,如图2所示:

图2 多次申明具有相同有效名称导致的异常