`

处理WCF异常的方式

阅读更多

任何程序都离不开对异常的处理,良好的异常处理方式可加快寻找出异常的根源,同时也需要避免暴露敏感信息到异常中。WCF这种典型的服务端和客户端交互的程序,服务端的异常更需要适当的处理。下面以一个简单的服务为例,说明WCF中处理异常的方式。

WCF服务定义如下,很明显方法Divide在divisor为0的时候将会抛出异常

View Code
复制代码
public class CalculateService : ICalculateService
    {
        public int Divide(int dividend, int divisor)
        {
            return dividend / divisor;
        }

        public int Add(int a, int b)
        {
            return a + b;
        }
    }
复制代码

客户端调用如下:

View Code
复制代码
 using (var client = new CalculateServiceClient())
            {
                try
                {
                    Console.WriteLine(client.Divide(200));
                }
                catch (FaultException ex)
                {
                    Console.WriteLine(ex.Reason);
                }

              }
复制代码

首先需要知道的是,WCF的异常信息默认是以FaultException的形式返回到客户端,FaultException的关键属性 Reason是对客户端反馈的最重要信息之一。以上客户端代码调用之后,默认的FaultException返回的Message信息如下:

由于内部错误,服务器无法处理该请求。有关该错误的详细信息,请 打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端,或在打开每个 Microsoft .NET Framework 3.0 SDK 文档的跟踪的同时检查服务器跟踪日志。

根据异常的提示,意思说如果要在客户端看到详细的Exception信息,那么请将ServiceBehavior对应的IncludeExceptionDetailInFaults属性设置为True,通常在配置中表现为如下设置:

View Code
复制代码
1 <serviceBehaviors>
2         <behavior>
3           <serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost:8733/CalculateService/"/>
4           <serviceDebug includeExceptionDetailInFaults="True" />
5         </behavior>
6       </serviceBehaviors>
复制代码

通过以上设置之后,客户端输出的内容为“尝试除以零”,这个提示信息跟原始的异常信息是一致,即返回的FaultException中的 Reason包含原始异常的Message的值,但是这样处理之后服务端所报出的异常信息直接传到了客户端,比如一些保密信息也可能输出到了客户端,因此 对于异常信息必须进行一个封装。最直接的形式莫过于在服务端就把异常给捕获了,并重新throw一个FaultException

服务端的代码改进如下,经过以下改进,那么客户端得到的信息仅仅是"操作失败",同时服务端也记录了异常信息(这时IncludeExceptionDetailInFaults是设置为False的)。

View Code
复制代码
1 try
2             {
3                 return dividend / divisor;
4             }
5             catch (Exception ex)
6             {
7                 Console.WriteLine(ex.Message);
8                 throw new FaultException("操作失败");
9             }
复制代码

当然这是FaultException的默认用法,FaultException还支持强类型的异常错误信息,返回更加丰富和精确的错误提示。假设 定义如下通用的一个FaultContract类型,将出错时的用户名和线程名字记录到异常信息中,因为异常信息也是通过SOAP格式传输的,因此跟定义 其他DataContract的方式一样。

CommonFaultContract
复制代码
1     [DataContract]
2     public class CommonFaultContract
3     {
4         [DataMember]
5         public string UserName { getset; }
6         [DataMember]
7         public string  ThreadName { getset; }
8     }
复制代码

那么服务方法的接口需要增加如下标记,如果不这样标记,那么客户端得到的异常类型依然是FaultException,而不是强类型的异常信息。

 [FaultContract(typeof(CommonFaultContract))]
 int Divide(int dividend, int divisor)

实现方法中抛出异常的部分代码改成如下:

异常处理
复制代码
1 catch (Exception ex)
2             {
3                 Console.WriteLine(ex.Message);
4                 throw new FaultException<CommonFaultContract>(new CommonFaultContract 
5                 {
6                     UserName = Environment.UserName,
7                     ThreadName = System.Threading.Thread.CurrentThread.Name
8                 }, "操作失败");
9             }
复制代码

 这时候重新生成客户端的代理类,然后更新客户端的代码如下,红色部分即获取强类型的异常错误信息。

View Code
复制代码
 1 try
 2                 {
 3                     Console.WriteLine(client.Divide(200));
 4                 }
 5                 catch (FaultException<CommonFaultContract> ex)
 6                 {
 7                     Console.WriteLine(ex.Detail.ThreadName);
 8                     Console.WriteLine(ex.Detail.UserName);
 9                     Console.WriteLine(ex.Reason);
10                 }
复制代码

当然在具体应用中还需要根据需求,返回不同的信息,构建不同的FaultContract。

  以上服务端捕获的异常方法,适用于方法比较少的情况,如果有十多个方法,一个个去写try catch然后做标记等,那么工作量会很大,而且代码也不利于重用。尝试寻找像MVC Controller那样的统一处理Exception的方式,将异常处理都放在基类中,那么只要继承与这个基类的方法都不需要去写try catch去捕获异常。但WCF中似乎没有这样的机制,放弃了这种做法。

  最近在研究Enterprise Lib中对WCF的支持时,发现Exception Block中还特地有针对WCF程序异常处理的解决方案,而且满足以上说道的需求,即可记录异常,又可对异常信息进行封装。更重要的时,自动处理运行时的 异常信息,不需要挨个方法的去写Try catch。秉承企业库的优秀传统,大部分工作还是通过配置就可以完成了,非常好的解决方案。下面介绍具体的使用步骤。

步骤一:

引用以下dll

Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll

Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.dll

Microsoft.Practices.EnterpriseLibrary.Common.dll

Microsoft.Practices.ObjectBuilder2.dll

步骤2:

在具体的实现类中,增加如下属性标记,其中WcfException为企业库中Exception Block中的一个异常处理策略,具体如何配置异常处理策略,请参考企业库的帮助文档。

[ExceptionShielding("WcfException")]
public class CalculateService : ICalculateService

那么只要增加了[ExceptionShielding("WcfException")]这个属性标记之后,所有运行时的异常都将交给策略名为WcfException的异常处理block来处理,在这里就可以执行一些异常记录以及异常封装的操作。

步骤3:

将异常信息封装为FaultException,这个动作也是通过配置来完成。在Exception节点中添加一个Fault Contract Exception Handler。

Fault Contract Exception Handler需要设置以下两个属性值

exceptionMessage:所有异常封装后的错误信息

faultContractType:即返回异常的faltContract类型,这个类型必须指定一个,哪怕方法中没有用到也要,如果方法中有用 到,那么客户端那边就能得到强类型FaultException,否则就是普通的FaultException。这里指定为之前定义的CommonFaultContract

对于faultContract类型的值,还可以通过PropertyMappings来自定义需要从原始异常信息中映射到faultContract的属性中,这个属性可选。

  经过以上步骤配置之后,服务端的程序就具备了自动处理异常的功能。客户端还是跟往常那样调用,不过具体是用FaultException捕获异 常还是FaultException<T>去捕获异常,还得根据定义方法中是否标记了FaultContract。之后若定义了其他服务接 口,同样也仅仅需要在实现类上加上[ExceptionShielding("WcfException")]标记即可。

0
0
分享到:
评论

相关推荐

    Silverlight捕捉WCF异常

    在IT行业中,Silverlight是一种基于.NET Framework的浏览器插件,用于创建丰富的...通过以上方式,开发者可以确保在Silverlight应用中有效管理和处理WCF服务可能出现的异常,从而提供更健壮、用户体验更好的应用程序。

    IIS部署WCF异常处理

    ### IIS部署WCF服务异常处理详解 #### 一、前言 在现代软件开发过程中,Web服务(尤其是WCF服务)的部署是一项常见的任务。然而,在实际部署过程中,经常会遇到各种各样的问题,尤其是在使用IIS作为服务宿主的情况...

    WCF错误异常demo

    本示例“WCF错误异常demo”将引导新手了解如何在WCF服务中自定义错误处理。 首先,让我们了解WCF中的错误处理机制。当服务方法抛出未捕获的异常时,WCF默认会生成一个FaultException,将其转换为SOAP错误并返回给...

    WCF编程方式访问Demo

    在本"**WCF编程方式访问Demo**"中,我们将探讨如何通过代码来实现WCF服务的启动和调用,这对于理解WCF工作原理以及在实际项目中灵活运用是非常有价值的。 1. **创建WCF服务** - 首先,我们需要创建一个WCF服务接口...

    WCF自定义异常

    通过这种方式,WCF允许你创建具有丰富信息的自定义异常,提高服务的可维护性和用户体验。同时,自定义异常还可以帮助你在服务边界保持一致的错误处理策略,使错误报告更加精确和可控。在开发WCF应用时,合理利用...

    WCF在同步和异常调用情况下的异常捕获

    总的来说,无论是在同步还是异步调用场景下,理解和正确处理WCF中的异常捕获是保证服务可靠性和客户端健壮性的关键。通过使用`FaultContract`,我们可以提供更详细的错误信息,使得客户端能够更有效地处理错误状况。...

    WCF基本异常处理模式[上篇].doc

    总结起来,WCF的异常处理机制包括了应用异常和基础设施异常的处理,通过`FaultException`和自定义错误合同提供了一种安全、可控的方式来传递异常信息。通过理解并利用这些机制,开发者可以编写出健壮且具有容错能力...

    wcf之契约和异常处理

    WCF提供了两种主要的异常处理方式:`FaultContract`和自定义错误处理。 #### `FaultContract` `FaultContract`允许服务通过契约公开可能引发的异常类型。这样,客户端可以根据接收到的异常信息做出适当反应。要在...

    wcf 跨域 post方式

    在IT行业中,Windows Communication Foundation(WCF)是微软提供的一种用于构建分布式系统的服务模型,它允许服务提供商和消费者之间进行安全、可靠的数据交换。当涉及到跨域通信时,通常会遇到浏览器的同源策略...

    构建WCF面向服务的应用程序系列课程(4):异常与错误处理

    ### 构建WCF面向服务的应用程序系列课程(4):异常与错误处理 #### WCF中的异常处理:深入解析 在《构建WCF面向服务的应用程序系列课程(4):异常与错误处理》中,讲师付仲恺,作为微软特邀开发专家、MVP,深入探讨...

    WCF

    在WCF中,服务是主要的工作单元,它们可以通过多种协议和传输方式暴露接口。服务契约定义了服务的行为,即服务可以提供什么操作。数据契约定义了服务之间交换的数据结构。绑定定义了服务如何与客户端通信,包括使用...

    ajax以GET和POST方式调用WCF

    本文将详细讲解如何使用Ajax以GET和POST方式调用WCF服务,包括带参数和不带参数的情况。 首先,我们需要理解Ajax的基本原理。Ajax通过JavaScript创建XMLHttpRequest对象,然后利用这个对象与服务器进行异步通信。...

    silverlight通过wcf处理word问题

    3. **优化性能**:考虑到Word Interop组件可能会影响性能,可以通过批量处理文档、减少不必要的操作等方式来提高效率。 ##### 4.3 使用第三方库 1. **选择合适的第三方库**:市面上存在多种用于操作Word文档的第三...

    构建WCF面向服务的应用程序系列课程(4):异常与错误处理.zip

    在构建Windows Communication Foundation (WCF)面向服务的应用程序时,异常和错误处理是不可或缺的部分。这一系列课程的第四部分专门探讨了如何在WCF服务中有效地管理异常和错误,以确保服务的稳定性和可靠性。以下...

    C#POST请求WCF服务

    本篇将深入探讨如何使用C#进行POST请求操作来调用WCF服务,并处理带有输入参数和返回值的JSON字符串。 首先,理解WCF服务的基础知识至关重要。WCF服务是一种能够跨越多个应用程序和网络边界通信的服务。它支持多种...

    WCF实例-多种部署方式

    本教程将深入探讨WCF的多种部署方式,结合实例代码和教程,帮助你理解如何在不同的环境中部署和管理WCF服务。 1. **基础概念** - **服务契约**:定义服务提供的操作和消息格式。 - **绑定**:指定服务与客户端...

    WCF for Windows Mobile 6

    异常处理在WCF应用中同样重要,它涉及到如何处理服务运行期间发生的异常情况。WCF提供了强大的故障处理机制,包括已声明的故障和特定的异常类,如FaultException,它们在客户端和服务器之间传递错误信息。此外,工作...

Global site tag (gtag.js) - Google Analytics