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. APP的功能分类及打包与发布的分类方式

    智能手机的出现改变了我们的生活,同时各种各样的APP充斥在我们的手机当中.那么我先现在在来熟悉一下APP的分类及其用途:工具类.社交类.信息类.娱乐类.生活类等几大类.我么了解了APP的用途分类,那么 ...

  2. unity 渲染第二步

    先不要用 unity shader 提供给你的转换矩阵,看看屏幕上的图形,你会学到更多. --- <unity 渲染箴言> 假设你 create 了一个 cube,放在默认的位置,默认的 ...

  3. Github提交PullRequest

    Github提交PullRequest工作流程: 以Kubernetes为例 1.   Fork Kubernetes到自己的Github目录 访问:https://github.com/kubern ...

  4. CentOS6.4 安装Redis

    按照下面步骤依次执行1.检查依赖,安装依赖 [root@ecs-3c46 ~]# whereis gcc gcc: /usr/bin/gcc /usr/lib/gcc /usr/libexec/gcc ...

  5. Winform取消用户按下键盘的事件

    1. 有时候针对某个控件,想取消它的所有键盘按下事件, 只需要为这个控件绑定keyDown事件即可,然后处理的代码如下: private void txtDeviceName_KeyDown(obje ...

  6. CCF 出现次数最多的数 201312-1

    出现次数最多的数 问题描述 试题编号: 201312-1 试题名称: 出现次数最多的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个正整数,找出它们中出现次数最多的 ...

  7. SSM批量插入和修改实现实例

    1.Service,自己对代码逻辑进行相应处理 /* 新增订单产品信息 */ List<DmsOrderProduct> insertOrderProductList = Lists.ne ...

  8. Apache 反向代理 丢失Authorization

    我后端API的服务器是Tomcat,而后端API验证是通过存放在头部Authorization的token值进行验证的. 我在测试Apache作为前端html解析的服务器时, 利用反向代理,把Api请 ...

  9. js 验证字符串是否全为中文

    js 验证字符串是否全为中文: function isChinese(str) { var reg = /^[\u4E00-\u9FA5]+$/; if(reg.test(str)){ return ...

  10. AngularJS中的动画实现

    AngularJS 动画 AngularJS 提供了动画效果,可以配合 CSS 使用. AngularJS 使用动画需要引入 angular-animate.min.js 库. <script ...