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. python设计模式--读书笔记

    GoF在其设计模式一书中提出了23种设计模式,并将其分为三类: 创建型模式 将对象创建的细节隔离开来,代码与所创建的对象的类型无关. 结构型模式 简化结构,识别类与对象间的关系,重点关注类的继承和组合 ...

  2. 后台微信开发入口+关键字 回复等 关注公众号回复 注意获取随机Token 微信的对接校验Token保存到数据库的只是做第一次的校验 其他对微信公众号的操作是去缓存中获取7200S的随机Token

    package com.epalmpay.controller.apiweixin; import com.epalmpay.commom.BaseController;import com.epal ...

  3. 设置开机自动运行vncserver

    a. 在/etc/rc.d/rc.local文件中加入下面行   /etc/init.d/vncserver startb. 编辑/etc/sysconfig/vncservers   VNCSERV ...

  4. Sql数据库收缩 语句特别快

    数据库在收缩的时候..使用菜单 >> 任务 >> 收缩 >> 文件 >> 数据,  特别慢..还会报错失败.. 但使用脚本 USE [dbName] G ...

  5. 理解session和cookie

    Session 与 Cookie 的作用都是为了保持访问用户与后端服务器的交互状态.它们有各自的优点,也有各自的缺陷,然而具有讽刺意味的是它们的优点和它们的使用场景又是矛盾的.例如,使用 Cookie ...

  6. 解决display none到display block 渲染时间过长的问题,以及bootstrap模态框导致其他框中input不能获得焦点问题的解决

    在做定制页面的时候,遇到这么一个问题,因为弹出框用的是bootstrap的自带的弹出框,控制显示和隐藏也是用自带的属性控制 控制显示,在触发的地方 例如botton上面加上 data-toggle=& ...

  7. unity状态机实现

    刚看了浅墨大神的文章让我对状态机有了进一步的理解 具体实现见装载的状态机文章 首先得有个总状态HeroineBaseState接口,其里面的方法主要是与行为相关的方法,让继承此接口的类来实现的 具体的 ...

  8. 关于重绘and重排

    在研究CSS3动画性能的时候,看到了重排两个字. 突然想到自己虽然听说过这么个东东,但一直也没深入研究之. 趁着当下正好有研究的劲头,所以一不做二不休,把这个point也给学习了. 同样是一番查找资料 ...

  9. mysql 5.6 windows7 解压缩版安装的坑

    从官网下载了解压缩版的mysql ,解压缩后,配置好环境变量,运行安装命令,提示我 缺失ddl文件,然后百度,找到了一个windows 系统组件扫描安装缺失组件的程序,然后继续安装,遇到了 初始化密码 ...

  10. lighttpd 与 gitweb 搭建服务器

    搭建 Git 仓库服务器 下载 gitweb 如果是用 debian 系的 Linux 发行版,可以使用 apt 下载安装可执行的 gitweb sudo apt-get install gitweb ...