解决方案:WCF客户端无法获取服务端抛出的异常详细信息
WCF客户端无法获取服务端抛出的异常详细信息,当WCF服务端抛出异常时当前通信channel中止,客户端获取的是下面的信息:
跟踪代码该异常是System.ServiceModel.CommunicationObjectFaultedException类型,无法获取具体的错误信息,将导致用户不明白系统究竟出了什么问题。
通过跟踪代码,发现在DAL层能辨别异常信息,如下图:
但是传到客户端只能取到ServiceChannel通信错误的CommunicationObjectFaultedException异常。
原理分析
要解释具体的原因,还得从信道(Channel)的两种分类形式说起。在上面一篇文章中,我们就谈到过:WCF通过信道栈实现了消息的编码、传输及 基于某些特殊功能对消息的特殊处理,而绑定对象是信道栈的缔造者,不同的绑定类型创建出来的信道栈具有不同的特性。就对会话的支持来讲,我们可以将信道分 为以下两种:
会话信道(Sessionful Channel):会话信道确保客户端和服务端之间传输的消息能够相互关联,但是信道的错误(Fault)会影响后续的消息交换;
数据报信道(Datagram Channel):即使在同一个数据报信道中,每次消息的交换都是相互独立,信道的错误也不会影响后续的消息交换。
由于上面的例子中,我们采用了WsHttpBinding,所以在默认条件下创建的信道(Channel)是会话信道(Sessionful Channel)。异常抛出后,当前信道的状态将变成Faulted,表示信道出现错误。错误的信道将不能继续用于后续的通信,即使是调用Close方法试图将其关闭也不行。
解决方案
我们在Web服务层用try catch 语法重新封装FaultException异常。
public class DataDictService : IDataDictService
{
/// <summary>
/// 删除一条数据字典记录
/// </summary>
/// <param name="loginTicket"></param>
/// <param name="keyValue">主键</param>
/// <param name="ORM_TypeName">ORM类型</param>
/// <returns></returns>
public bool Delete(byte[] loginTicket, string keyValue, string ORM_TypeName)
{
try
{
Loginer loginer = WebServiceSecurity.ValidateLoginer(loginTicket);
dalBaseDataDict dict = dalBaseDataDict.CreateDalByORM(loginer, ORM_TypeName);//创建DAL层实例
return dict.Delete(keyValue);
}
catch (Exception ex)
{
throw new FaultException(ex.Message);//转换为客户端可截取的异常类型(FaultException)信息。
//throw new FaultException("删除记录发生错误!");//或者提示更具体的异常信息,屏蔽WCF系统内部消息。
}
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
客户端获取FaultException异常成功!
扫一扫加微信