There are multiple ways to do error handling in WCF as listed by Pedram Rezaei Blog.

The default way that WCF allows errors

message to display is by setting IncludeExceptionDetailInFaults Property to true in web.config or on the service attribute but this is only recommended when you need to debug you development code not in your shipped/release code.

In Web.config file

In the web.config file of the WCF service the includeExceptionDetailFaults attribute set it to true.  With this action every endpoint associated to WCF service will send managed exception information.

<system.serviceModel>
<services>
<service name="ZeytinSoft.WCF.OliveService"
behaviorConfiguration="OliveDebugServiceConfiguration">
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="OliveDebugServiceConfiguration">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<system.serviceModel>
    <services>
        <service name="ZeytinSoft.WCF.OliveService"
                         behaviorConfiguration="OliveDebugServiceConfiguration">
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="OliveDebugServiceConfiguration">
                <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

In Attribute

Another way is setting the IncludeExceptionDatailInFaults property to true using the ServiceBehaviorAttribute.

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class OliveService{ }
1
2
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class OliveService{ }

That is fine and dandy but it is definitely not recommended for production server, you don’t want an stack trace to show up when someone is viewing it on the webpage for this service.

The IErrorHandler interface

The basic form of error logging in WCF is to use the IErrorHandler interface, which enables developers to customize the default exception reporting and propagation, and provides for a hook for custom logging.

public interface IErrorHandler
{
bool HandleError(Exception error);
void ProvideFault(Exception error,MessageVersion version,ref Message fault);
}
1
2
3
4
5
public interface IErrorHandler
{
   bool HandleError(Exception error);
   void ProvideFault(Exception error,MessageVersion version,ref Message fault);
}

Another thing to note is we need to implement the IServiceBehavior also since installing our own custom implementation of IErrorHandler requires adding it to the desired dispatcher. Since we need to treat the extensions as custom service behaviors in order for it to work.

public interface IServiceBehavior
{
void AddBindingParameters(ServiceDescription description,
ServiceHostBase host,
Collection &lt;ServiceEndpoint&gt; endpoints,
BindingParameterCollection parameters);

void ApplyDispatchBehavior(ServiceDescription description,
ServiceHostBase host);

void Validate(ServiceDescription description,ServiceHostBase host);
}

1
2
3
4
5
6
7
8
9
10
11
12
public interface IServiceBehavior
{
   void AddBindingParameters(ServiceDescription description,
                             ServiceHostBase host,
                             Collection &lt;ServiceEndpoint&gt; endpoints,
                             BindingParameterCollection parameters);
 
   void ApplyDispatchBehavior(ServiceDescription description,
                              ServiceHostBase host);
 
   void Validate(ServiceDescription description,ServiceHostBase host);
}

Rather than just calling Log4Net I create a class called Logger which decouples log4net so that one can use any logging framework by using a dependency injection framework. (Code not listed)

Back to building our own ErrorHandler, ServiceBehavior with Attribute, the code is listed below

[AttributeUsage(AttributeTargets.Class)]
public class OliveErrorHandlerBehaviorAttribute : Attribute, IServiceBehavior, IErrorHandler
{
protected Type ServiceType { get; set; }
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
//Dont do anything
}

public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection &lt;ServiceEndpoint&gt; endpoints, BindingParameterCollection bindingParameters)
{
//dont do anything
}

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
ServiceType = serviceDescription.ServiceType;
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(this);
}
}

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
fault = null; //Suppress any faults in contract
}

public bool HandleError(Exception error)
{
Logger.LogException(error); //Calls log4net under the cover
return false;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[AttributeUsage(AttributeTargets.Class)]
public class OliveErrorHandlerBehaviorAttribute : Attribute, IServiceBehavior, IErrorHandler
{
protected Type ServiceType { get; set; }
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
//Dont do anything
}
 
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection &lt;ServiceEndpoint&gt; endpoints, BindingParameterCollection bindingParameters)
{
//dont do anything
}
 
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
ServiceType = serviceDescription.ServiceType;
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(this);
}
}
 
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
fault = null; //Suppress any faults in contract
}
 
public bool HandleError(Exception error)
{
Logger.LogException(error); //Calls log4net under the cover
return false;
}
}

Now one can just add an attribute to the WCF service code to log our error message to log4net or whatever logging framework that you may be using.

[ServiceContract]
[OliveErrorHandlerBehavior]
public class OliveService{ }
1
2
3
[ServiceContract]
[OliveErrorHandlerBehavior]
public class OliveService{ }

There is also another way by using the web.config and adding the error logging to all the services listed by Stever B in his blog, but I find that does not give me the flexibility that I wanted, I may want to log some but not others etc.

how to do error handing with WCF by using attributes to log your errors z的更多相关文章

  1. 使用WCF的Trace与Message Log功能

      原创地址:http://www.cnblogs.com/jfzhu/p/4030008.html 转载请注明出处   前面介绍过如何创建一个WCF Service http://www.cnblo ...

  2. mysqldump: Got error: 1556: You can't use locks with log tables. when using LOCK TABLES

    mysqldump: Got error: 1556: You can't use locks with log tables. when using LOCK TABLES 我是把一些mysqldu ...

  3. [mysql] ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.

    今天安装mysql遇到这样一个问题: ERROR 1862 (HY000): Your password has expired. To log in you must change it using ...

  4. 【故障处理】ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

    今天在使用冷备份文件重做从库时遇到一个报错,值得研究一下. 版本:MySQL5.6.27 一.报错现象 dba:(none)> start slave; ERROR (HY000): Slave ...

  5. 安装RabbitMQ编译erlang时,checking for c compiler default output file name... configure:error:C compiler cannot create executables See 'config.log' for more details.

    checking for c compiler default output file name... configure:error:C compiler cannot create executa ...

  6. postman Installation has failed: There was an error while installing the application. Check the setup log for more information and contact the author

    Error msg: Installation has failed: There was an error while installing the application. Check the s ...

  7. jmeter3.2生成图形html遇到的问题Error in NonGUIDriver java.lang.IllegalArgumentException: Results file:log is not empty

    遇到Creating summariser <summary> Error in NonGUIDriver java.lang.IllegalArgumentException: Resu ...

  8. (转)mysqldump: Got error: 1556: You can't use locks with log tables.

    mysqldump: Got error: 1556: You can't use locks with log tables. 原文:http://blog.51cto.com/oldboy/112 ...

  9. mysql 主从关系ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

    连接 amoeba-mysql出现Could not create a validated object, cause: ValidateObject failed mysql> start s ...

随机推荐

  1. C# DataTable 用法

    1.创建DataTable DataTable dataTable = new DataTable(); //创建一个空表 2.创建DataRow DataRow row = dataTable.Ne ...

  2. python+selenium+pychar安装

    python3.5(在百度输入python进入python官网-downloads-Windows-然后选择要下载的版本(可执行安装包,若电脑为32位的选择×86,若为64的选择×64)) selen ...

  3. BottomSheetDialogFragment 如何设置高度和禁止滑动

    主要是获取dialog 的BottomSheetBehavior 然后设置 setPeekHeight 和 BottomSheetCallback. private BottomSheetBehavi ...

  4. ubuntu 18 常用软件安装

    主要内容 1.安装 Ubuntu 18.04 LTS 2.安装 Google Chrome 3.安装 OpenVPN Client 4.安装 Docker CE 5.安装 MySQL Server 转 ...

  5. 什么是DDL,DCL,DML

    1.DCL 数据库控制语言,全称是Data Control Language 关键字类型:grant.remove 2.DDL 数据库定义语言,全称是Data Definition Language ...

  6. 导入数据到HBase的方式选择

    Choosing the Right Import Method If the data is already in an HBase table: To move the data from one ...

  7. 关于echart没有数据显示暂无数据

    对于echart当没有数据的时候怎么显示, 首先,如果你的series的值为空值的话,曲线将是一片空白,什么都不会有,所以在这里就要进行一个判断,如果没有值的话,人为的添加一个键 if(Object. ...

  8. <数据挖掘导论>读书笔记4--其他分类技术

    1.基于规则的分类器 2.最近邻分类器 3.贝叶斯分类器 4.人工神经网络 5.支持向量机 6.组合方法 7.不平衡类问题 8.多类问题

  9. Linux Kernel文件系统写I/O流程代码分析(二)bdi_writeback

    Linux Kernel文件系统写I/O流程代码分析(二)bdi_writeback 上一篇# Linux Kernel文件系统写I/O流程代码分析(一),我们看到Buffered IO,写操作写入到 ...

  10. step3: 创建jobbole爬虫

    scrapy startproject Redbacktestcd Redbacktest 创建jobbole爬虫 scrapy genspider jobbole2 blog.jobbole.com ...