WCF 学习笔记之异常处理

WCF 学习笔记之异常处理

1:WCF异常在配置文件

WCF 学习笔记之异常处理
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceDebuBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors> <services>
<service name="Artech.WcfServices.Service.CalculatorService" behaviorConfiguration="serviceDebuBehavior">
<endpoint address="http://127.0.0.1:3721/calculatorservice"
binding="ws2007HttpBinding"
contract="Artech.WcfServices.Service.Interface.ICalculator" />
</service>
</services>
</system.serviceModel>
</configuration>
WCF 学习笔记之异常处理

2:也可以直接在服务上直接用特性进行设定

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]

public class CalculatorService:ICalculator

{

}

上面两种方式实现的效果是一样的;

3:自定义异常信息

(1)直接通过FaultException直接指定错误的信息

WCF 学习笔记之异常处理
using System.ServiceModel;
namespace Artech.WcfServices.Service
{
public class CalculatorService : ICalculator
{
public int Divide(int x, int y)
{
if (0 == y)
{
throw new FaultException("被除数y不能为零!");
}
return x / y; }
}
}
WCF 学习笔记之异常处理

相应的配置文件内容为:

WCF 学习笔记之异常处理
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceDebuBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors> <services>
<service name="Artech.WcfServices.Service.CalculatorService" behaviorConfiguration="serviceDebuBehavior">
<endpoint address="http://127.0.0.1:3721/calculatorservice"
binding="ws2007HttpBinding"
contract="Artech.WcfServices.Service.Interface.ICalculator" />
</service>
</services>
</system.serviceModel>
</configuration>
WCF 学习笔记之异常处理

(2)通过FaultException<TDetail>采用自定义类型封装错误

首先我们看一下一个实例;注意Interface层里的CalculaltionError.cs这个是自定义封装的错误类;

WCF 学习笔记之异常处理

CalculaltionError.cs类代码如下:它是一个数据契约

WCF 学习笔记之异常处理
using System.Text;
using System.Runtime.Serialization; namespace Artech.WcfServices.Service.Interface
{
[DataContract]
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; }
} }
WCF 学习笔记之异常处理

契约里的定义如下:为了确保错误细节对象能够被正常序列化和反序列化,要按照如下的方式通过FaultContractAttribute特性为操作定义基于CalculationError类型的错误契约(错误契约的一些注意点在下面会讲到);

WCF 学习笔记之异常处理
namespace Artech.WcfServices.Service.Interface
{
[ServiceContract(Namespace = "http://www.artech.com/")]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]
int Divide(int x, int y);
}
}
WCF 学习笔记之异常处理

服务实现里直接抛出一个FaultException<CalculationError>,并创建一个CalculationError对象作为该异常对象的细节;

WCF 学习笔记之异常处理
using System.ServiceModel;
namespace Artech.WcfServices.Service
{
public class CalculatorService : ICalculator
{
public int Divide(int x, int y)
{
if (0 == y)
{
var error = new CalculationError("Divide", "被除数y不能为零!");
throw new FaultException<CalculationError>(error, error.Message);
}
return x / y;
}
}
}
WCF 学习笔记之异常处理

服务实现的配置文件内容如下:

WCF 学习笔记之异常处理
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceDebuBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors> <services>
<service name="Artech.WcfServices.Service.CalculatorService" behaviorConfiguration="serviceDebuBehavior">
<endpoint address="http://127.0.0.1:3721/calculatorservice"
binding="ws2007HttpBinding"
contract="Artech.WcfServices.Service.Interface.ICalculator" />
</service>
</services>
</system.serviceModel>
</configuration>
WCF 学习笔记之异常处理

客户端调用相关的异常处理;获得FaultException<CalculationError>类型的异常

WCF 学习笔记之异常处理
using System.ServiceModel;
using Artech.WcfServices.Service.Interface;
namespace Artech.WcfServices.Clients
{
class Program
{
static void Main(string[] args)
{
using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
{
ICalculator calculator = channelFactory.CreateChannel();
using (calculator as IDisposable)
{
try
{
int result = calculator.Divide(1, 0);
}
catch (FaultException<CalculationError> ex)
{
Console.WriteLine("运算错误");
Console.WriteLine("运算操作:{0}", ex.Detail.Operation);
Console.WriteLine("错误消息: {0}", ex.Detail.Message);
(calculator as ICommunicationObject).Abort();
}
}
}
Console.Read(); }
} }
WCF 学习笔记之异常处理

客户端配置信息如下:

WCF 学习笔记之异常处理
<configuration>
<system.serviceModel>
<client>
<endpoint name="calculatorservice"
address= "http://127.0.0.1:3721/calculatorservice"
binding="ws2007HttpBinding"
contract="Artech.WcfServices.Service.Interface.ICalculator"/>
</client>
</system.serviceModel>
</configuration>
WCF 学习笔记之异常处理

*接下来讲解关于错误契约的注意点:

对于错误契约的运用不仅仅在将自定义的错误细节类型应用到服务契约相应操作上时才要显式地在操作方法上应用FaultContracAttribute特性;对于一些基元类型(比如Int32, String等)也要这么做;

WCF 学习笔记之异常处理
    public class CalculatorService : ICalculator
{
public int Divide(int x, int y)
{
if (0 == y)
{
throw new FaultException<String>("不能为0");
}
return x / y;
}
}
WCF 学习笔记之异常处理

契约如下:

WCF 学习笔记之异常处理
namespace Artech.WcfServices.Service.Interface
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(string))]
int Divide(int x, int y);
}
}
WCF 学习笔记之异常处理

当然它是可以多次声明针对多个异常的处理

WCF 学习笔记之异常处理
namespace Artech.WcfServices.Service.Interface
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]
[FaultContract(typeof(string))]
int Divide(int x, int y);
}
}
WCF 学习笔记之异常处理

若是两个是相同类型的则要增加Name 或者Namespace来区别开;若是Name一样类型不一样同样会报错;

WCF 学习笔记之异常处理
    [ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError),Name="CalualationError")]
[FaultContract(typeof(CalculationError),Name="CalualationException")]
int Divide(int x, int y);
}
WCF 学习笔记之异常处理

(4)通过XmlSerializer对错误细节对象进行序列化([XmlSerializerFormat(SupportFaults=true)])因为WCF默认是采用序列化器是DataContractSerializer(WCF提供的两种序列化器DataContractSerializer 和 XmlSerializer)

WCF 学习笔记之异常处理
    [ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]
[XmlSerializerFormat(SupportFaults=true)]
int Divide(int x, int y);
}
WCF 学习笔记之异常处理

封装的错误类如下:

WCF 学习笔记之异常处理
    [Serializable]
public class CalculationError
{
[XmlAttributeAttribute("op")]
public string Operation { get; set; }
[XmlElement("Error")]
public string Message { get; set; }
}
WCF 学习笔记之异常处理
 
 
 
标签: WCF
上一篇:Java源码分析系列


下一篇:java---数据格式的验证