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.

<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.

时间: 2024-10-04 08:09:56

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

mysql5.7密码过期ERROR 1862 (HY000): Your password has expired. To log in you must change

环境: ubuntu14.04  mysql5.7 一.mysql5.7 密码过期问题 报错: ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords. 翻译: 错误1862(HY000):你的密码已经过期.登录必须改变它使用一个客户端,支持过期的密码. 解决方法: 1. 用忽略授权表的方法进入mysql  

[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 a client that supports expired passwords. 意思就是密码过期了. 修改密码了: mysql> SET PASSWORD = PASSWORD('abc'); ERROR 1819 (HY000): Your password does not satisfy

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

今天在使用冷备份文件重做从库时遇到一个报错,值得研究一下. 版本:MySQL5.6.27 一.报错现象 dba:(none)> start slave; ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository 这个时候查看error.log: 2017-07-17 16:19:02 9022 [ERROR] Failed to open the relay log '.

mysqldump: Got error: 1556: You can&#39;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 我是把一些mysqldump语句放在一个批量命令文件(传说中的.sh文件)中执行的,而当我把这些mysqldump语句分离开来一个一个执行的时候,我发现是没有任何错误的,于是在网络上找了一些资料:发现是mysql默认数据库里的logs表,不能被加锁(lock tables)引起的.于是我测试了一下,把关于mysql这个默认

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

checking for c compiler default output file name... configure:error:C compiler cannot create executables See 'config.log' for more details. 打开config.log查看明细: 网上找了下,说是没有安装cpp,libc5-devel,而在redhat中指的是glibc,glibc-devel,cpp,查看是否安装,: 果然没有,然后安装: 再次编译,发现换了一

ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

该问题的一般是由relay log没有在配置文件定义所致. 1.问题描述: mysql> start slave; mysql> system perror 1872 MySQL error code 1872 (ER_SLAVE_RLI_INIT_REPOSITORY): Slave failed to initialize relay log info structure from the repository 2.处理办法2.1.修改配置文件 诸如在my.cnf配置文件中添加如下项: r

MAC下cmake安装

可以参考网上手动下载cmake的源码包进行安装,http://www.cmake.org/download/ 解压后运行sudo ./bootstrap && sudo make && sudo make install 但是在执行./bootstrap的时候报以下错误: /Users/baidu/cmake-3.9.0/Source/cmSystemTools.cxx:2061:39: error: expected ';' after expression exe_di

WCF basicHttpBinding之Transport Security Mode, clientCredentialType=&quot;None&quot;

原创地址:http://www.cnblogs.com/jfzhu/p/4071342.html 转载请注明出处 前面文章介绍了<WCF basicHttpBinding之Message Security Mode>如何basicHttpBinding的Message Security Mode,并且clientCredentialType用的是certificate. 本文演示basicHttpbinding使用Transport Security Mode,并且clientCredenti

configure编译时,出现 configure: error: C compiler cannot create executables错误解决 .

今天在服务器上安装bind9.9.2的时候,gcc和gcc-c++已经安装过了,但是./configure的时候还是报错: checking build system type... x86_64-unknown-linux-gnu   checking host system type... x86_64-unknown-linux-gnu   checking whether make sets $(MAKE)... yes   checking for gcc... gcc   check