WCF 学习笔记之异常处理

1: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>

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

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]

public class CalculatorService:ICalculator

{

}

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

3:自定义异常信息

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

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; }
}
}

相应的配置文件内容为:

<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>

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

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

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

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; }
} }

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

namespace Artech.WcfServices.Service.Interface
{
[ServiceContract(Namespace = "http://www.artech.com/")]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]
int Divide(int x, int y);
}
}

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

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;
}
}
}

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

<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>

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

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(); }
} }

客户端配置信息如下:

<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>

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

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

    public class CalculatorService : ICalculator
{
public int Divide(int x, int y)
{
if (0 == y)
{
throw new FaultException<String>("不能为0");
}
return x / y;
}
}

契约如下:

namespace Artech.WcfServices.Service.Interface
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(string))]
int Divide(int x, int y);
}
}

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

namespace Artech.WcfServices.Service.Interface
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]
[FaultContract(typeof(string))]
int Divide(int x, int y);
}
}

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

    [ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError),Name="CalualationError")]
[FaultContract(typeof(CalculationError),Name="CalualationException")]
int Divide(int x, int y);
}

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

    [ServiceContract]
public interface ICalculator
{
[OperationContract]
[FaultContract(typeof(CalculationError))]
[XmlSerializerFormat(SupportFaults=true)]
int Divide(int x, int y);
}

封装的错误类如下:

    [Serializable]
public class CalculationError
{
[XmlAttributeAttribute("op")]
public string Operation { get; set; }
[XmlElement("Error")]
public string Message { get; set; }
}
 
 
 
标签: WCF

WCF 学习笔记之异常处理的更多相关文章

  1. WCF学习笔记之事务编程

    WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...

  2. WCF学习笔记之传输安全

    WCF学习笔记之传输安全 最近学习[WCF全面解析]下册的知识,针对传输安全的内容做一个简单的记录,这边只是简单的记录一些要点:本文的内容均来自[WCF全面解析]下册: WCF的传输安全主要涉及认证. ...

  3. WCF 学习笔记之双工实现

    WCF 学习笔记之双工实现 其中 Client 和Service为控制台程序 Service.Interface为类库 首先了解契约Interface两个接口 using System.Service ...

  4. Python学习笔记之异常处理

    1.概念 Python 使用异常对象来表示异常状态,并在遇到错误时引发异常.异常对象未被捕获时,程序将终止并显示一条错误信息 >>> 1/0 # Traceback (most re ...

  5. WCF学习笔记(2)——使用IIS承载WCF服务

    通过前面的笔记我们知道WCF服务是不能独立存在,必须“寄宿”于其他的应用程序中,承载WCF服务的应用程序我们称之为“宿主”.WCF的多种可选宿主,其中比较常见的就是承载于IIS服务中,在这里我们来学习 ...

  6. WCF学习笔记1--发布使用配置文件的服务

    关于WCF的入门网上资料很多,可以参考蒋金楠老师的博客http://www.cnblogs.com/artech/archive/2007/02/26/656901.html,我是从这篇博客开始学习的 ...

  7. WCF学习笔记(1)——Hello WCF

    1.什么是WCF Windows Communication Foundation(WCF)是一个面向服务(SOA)的通讯框架,作为.NET Framework 3.0的重要组成部分于2006年正式发 ...

  8. WCF学习笔记(基于REST规则方式)

    一.WCF的定义 WCF是.NET 3.0后开始引入的新技术,意为基于windows平台的通讯服务. 首先在学习WCF之前,我们也知道他其实是加强版的一个面向服务(SOA)的框架技术. 如果熟悉Web ...

  9. [WCF学习笔记] 我的WCF之旅(1):创建一个简单的WCF程序

    近日学习WCF,找了很多资料,终于找到了Artech这个不错的系列.希望能从中有所收获. 本文用于记录在学习和实践WCF过程中遇到的各种基础问题以及解决方法,以供日后回顾翻阅.可能这些问题都很基础,可 ...

随机推荐

  1. HDU5014Number Sequence(贪心)

    HDU5014Number Sequence(贪心) 题目链接 题目大意: 给出n,然后给出一个数字串,长度为n + 1, 范围在[0, n - 1].然后要求你找出另外一个序列B,满足上述的要求,而 ...

  2. iOS7 UIKit动力学-碰撞特性UICollisionBehavior 上

    我们谈到了重力上述财产UIGravityBehavior这个类. 非常明确的看法,当我们添加的属性的严重性后,,苹果UIview像掉进无底洞,地下坠,不断的加速.而如今呢,我们要在这个手机屏幕上,加入 ...

  3. 对JSON数组对象排序-有键相同的元素,分组数量不一致,可采用如下的JS进行循环表格输出

    var now=eval(data.data); // now.sort(sortBy('bigIdOrder', true, parseInt)); var tab=""; va ...

  4. curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in

    当系统开启safe_mode和 open_basedir,在程序中使用以下语句 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); 并且遇到301,302状态 ...

  5. 在windows server里,对于同一个账号,禁止或允许多个用户使用该账户,同时登录

    开始 -> 运行 -> gpedit.msc -> 本地计算机 策略 -> 计算机配置 -> 管理模板 -> Windows 组件 -> 远程桌面服务 -&g ...

  6. 编程乐趣:C#获取日期所在周、月份第一和最后一天

    原文:编程乐趣:C#获取日期所在周.月份第一和最后一天 写了个小功能,需要用到以周为时间段,于是写了个获取周第一和最后一天的方法,获取月份的第一和最后一天就比较简单了.代码如下: public cla ...

  7. lua及luci学习

    由于项目需要对Luci进行修改,所以这里开始地luci进行较深入的研究. 探索其中的运行路径. Openwrt默认的HTTP服务器为uhttpd,该WEB服务器是由Luci的开发者自行开发的,非常小巧 ...

  8. 题注Oracle数据库的网络连接原理

    版权声明:本文博客原创文章,博客,未经同意,不得转载.

  9. 安装Windows2003操作系统 - 初学者系列 - 学习者系列文章

    Windows 2003是一款经典的服务器操作系统.以前笔者工作的时候就是用的这款操作系统来进行编程的.下面就对该操作系统的安装进行介绍(部分步骤参见XP的安装http://www.cnblogs.c ...

  10. C#中使用消息队列RabbitMQ

    在C#中使用消息队列RabbitMQ 2014-10-27 14:41 by qy1141, 745 阅读, 2 评论, 收藏, 编辑 1.什么是RabbitMQ.详见 http://www.rabb ...