how to do error handing with WCF by using attributes to log your errors z

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.
<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.
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.
{
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.
{
void AddBindingParameters(ServiceDescription description,
ServiceHostBase host,
Collection <ServiceEndpoint> 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 <ServiceEndpoint> 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
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 <ServiceEndpoint> 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 <ServiceEndpoint> 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.
[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的更多相关文章
- 使用WCF的Trace与Message Log功能
原创地址:http://www.cnblogs.com/jfzhu/p/4030008.html 转载请注明出处 前面介绍过如何创建一个WCF Service http://www.cnblo ...
- 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 ...
- [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 ...
- 【故障处理】ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
今天在使用冷备份文件重做从库时遇到一个报错,值得研究一下. 版本:MySQL5.6.27 一.报错现象 dba:(none)> start slave; ERROR (HY000): Slave ...
- 安装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 ...
- 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 ...
- 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 ...
- (转)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 ...
- 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 ...
随机推荐
- 点击劫持(click jacking)
什么是点击劫持劫持原理劫持案例代码示例优酷频道刷粉的POC腾讯微博刷粉防御 什么是点击劫持 点击劫持,clickjacking,也被称为UI-覆盖攻击.这个词首次出现在2008年,是由互联网安全专家罗 ...
- CSS ::Selection的使用方法
大家都知道浏览器对选中的文本默认样式都是统一的,Windows下是一个深蓝色的背景,白字的前景,而在Mac下是一个淡蓝色背景,白色字体,就如上图所展示的一样,自从有了这个“::selection”选择 ...
- js模块加载框架 sea.js学习笔记
seajs实现了JavaScript 的 模块开发及按模块加载.用来解决繁琐的js命名冲突,文件依赖等问题,其主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载. 官方文档:http:/ ...
- 公用表表达式 (CTE)、递归
指定临时命名的结果集,这些结果集称为公用表表达式 (CTE).公用表表达式可以包括对自身的引用.这种表达式称为递归公用表表达式. 对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分 ...
- 架构实战项目心得(四):使用Nexus配置Maven私有仓库
一.安装配置Nexus 1. 下载nexus https://www.sonatype.com/download-oss-sonatype 2. 解压:tar -zxfnexus-3.5.2-01 ...
- Web后台模拟前端post(带NTLM验证)
using System.Data; using System.Net; using System.IO; using System.Net.Http; using System.Web; using ...
- Silverlight & Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)
说到对象的旋转,或许就会联想到对象角度的概念.对象的旋转实现实际上就是利用对象的角度改变来实现的位置变换,在<Silverlight & Blend动画设计系列二:旋转动画(Rotate ...
- 网站部署中遇到的问题-未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项
问题描述: 运行站点抛出错误:未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项 原因: 应用程序池没有启用32位程序. 解决方法: 找到站点对应的应用程序池,设置启用32 ...
- 二、redis的配置
# redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...
- linux cut: invalid byte, character or field list Try 'cut --help' for more information.
1. 概述 centos执行简单shell 脚本 报错 cut: invalid byte, character or field listTry 'cut --help' for more info ...