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 ...
随机推荐
- python namedtuple命名元组
from collections import namedtuple Animal=namedtuple('Animal','name age type') perry=Animal(name='pe ...
- (转)Linux-HA开源软件Heartbeat(配置篇)
原文:http://ixdba.blog.51cto.com/2895551/548625 http://gzsamlee.blog.51cto.com/9976612/1828870 Linux-H ...
- Oracle 维护数据的完整性 一 约束
简介:约束用于确保数据库满足特定的商业规则.在Oracle中,约束包括以下几种: 1.not null 非空约束 该劣质不能为null 2.unique 唯一约束 ...
- Python数据分析学习之Numpy
Numpy的简单操作 import numpy #导入numpy包 file = numpy.genfromtxt("文件路径",delimiter=" ",d ...
- 我的Python升级打怪之路【六】:面向对象(一)
面向对象的概述 面向过程:根据业务逻辑从上到下写代码 函数式:将其功能代码封装到函数中,日后便无需编写,仅仅调用即可 [执行函数] 面向对象:对函数进行分类和封装.[创建对象]==>[通过对象执 ...
- 关于80286——《x86汇编语言:从实模式到保护模式》读书笔记15
一.80286的工作模式 80286首次提出了实模式和保护模式的概念. 实模式:和8086的工作方式相同: 保护模式:提供了存储器管理机制和保护机制,支持多任务. 二.80286的寄存器 (一)通用寄 ...
- 批量插入Oracle,遇到CLob字段慢的解决办法
在一次执行批量插入到Oracle表,其他一个字段设置为CLOB,但没有内容,在插入时,在代码指定为CLOB类型,插入相当慢,后来改为VarChar2,速度就上去了,经测试,插入一个65535个字符,没 ...
- jstl缺包时的报错
jsp中:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 报错: ...
- java启动线程时 extends与implements的一个差异
java extends与implements在使用时的一个差异: Implements: public class ThreadImplementsTest implements Runnable{ ...
- 100个实用的CSS技巧,以及遇见的问题和解决方案。
前言 本篇文章将会持续更新,我会将我遇见的一些问题,和我看到的实用的CSS技巧记录下来,本篇文章会以图文混排的方式写下去.具体什么时候写完我也不清楚,反正我的目标是写100个. 本案例都是经本人实测 ...