WCF基础教程之异常处理:你的Try..Catch语句真的能捕获到异常吗?
2015-01-23 09:11
627 查看
在上一篇WCF基础教程之开篇:创建、测试和调用WCF博客中,我们简单的介绍了如何创建一个WCF服务并调用这个服务。其实,上一篇博客主要是为了今天这篇博客做铺垫,考虑到网上大多数WCF教程都是从基础讲起的,大家平时工作可能只是去调用和修改WCF的一些方法,而并未创建和配置过WCF,如果大家通过网上的教程去一步一步的创建和配置WCF,中途遇到错误,特别是WCF的配置这块很容易出错,难免会浪费时间。今天,我们就主要来说一下WCF中服务端和客户端的异常处理。
一、WCF异常处理机制
接着昨天的例子,我们在UserService中添加一个新的方法,或者直接修改DoWork方法,抛出一个异常,代码如下:
下面,我们在客户端调用这个方法,代码如下:
这里值得注意的是,在异步方法执行完成后,参数e会携带WCF抛出的异常信息,保存在e.Error中。下面我们按下F5,来执行看看会发生什么,如图:
View Code
然后,修改UserService的代码如下:
然后,我们在UserService上面,点击鼠标右键,在浏览器中预览一下,然后再客户端上的UserServiceReference上面,点击右键,更新服务引用,然后我们按Ctrl + F5,以release模式运行项目(这样不会中断),如图:
我们看到,这次显示了不同的错误,但是依然没有抛出真正的异常信息,我们还是不知道哪里出现错了。不过根据提示消息,我们可以看到解决办法,然后打开webConfig,寻找includeExceptionDetailInFaults,果然有这个配置,如图:
我们修改includeExceptionDetailInFaults的值为true,然后再执行,我们看到了如下信息:
哈哈,终于看到真正的异常信息了。
下面再来说一种方法,不修改webconfig文件,如图:
当然,我们也可以完整的将WCF的异常的抛给客户端(服务端不做任何错误处理),但是这样可能会泄露一些敏感信息,并不安全。更多关于WCF异常处理的信息,可以参考园内大牛的博客:
WCF技术剖析之二十一: WCF基本的异常处理模式[上篇]
WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
WCF技术剖析之二十一:WCF基本异常处理模式[下篇]
二、客户端的调用WCF和异常处理
下面,我们修改客户端代码,添加一个代理类,来对WCF的调用进行一些封装,关于WCF中使用回调函数,可以参考我之前的这篇博客Silverlight中异步调用WCF服务,传入回调函数,代码如下:
这里客户端的异常e.Error可以通过回调函数传递给页面,然后做处理。然后,我们修改UserService,如图:
然后,更新服务引用,我们调用这个WCF方法,加上Try...Catch...,大概就变成了下面这个样子,如图:
这时我们按下F5运行,会看到弹出了我们返回的结果:"WCF Result"。
下面我们在显示结果前加些代码,如图:
然后,F5运行,猜猜会出现什么情况,按照我们所想的,应该是弹出一个消息框,对吧,但是,实际情况是这样的,如图:
咦,为什么我们写的Try...Catch...没有捕获到异常呢?代码明明在Try...Catch...里面啊~~,到这里,我想你们应该清楚我这边博客标题的含义了吧~~
如果之前一直是这样的写的,以后就要赶紧改啦~~
其实,我们出现异常的这段代码,是通过一个Lamda表达式传进来的一个匿名委托,相当于一个独立的方法,所以这个方法根本就不在你的Try...Catch...的作用域内。(说的不对,还请指正)。
所以,将Try...Catch...写到内部就可以了,修改代码如下,就可以了,如图:
到这里,就算是说完了。这里提醒一下大家以后写代码,测试的时候一定要下断点全部走到,特别是异常处理部分。最后,祝大家工作愉快,欢迎加入QQ交流群,一起学习交流。
作者:雲霏霏
QQ交流群:243633526
博客地址:http://www.cnblogs.com/yunfeifei/
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
如果大家感觉我的博文对大家有帮助,请推荐支持一把,给我写作的动力。
一、WCF异常处理机制
接着昨天的例子,我们在UserService中添加一个新的方法,或者直接修改DoWork方法,抛出一个异常,代码如下:
[OperationContract] public void GetMessage() { throw new Exception("System Error!"); }
下面,我们在客户端调用这个方法,代码如下:
public void GetData() { UserServiceReference.UserServiceClient client = new UserServiceReference.UserServiceClient(); client.GetMessageCompleted += client_GetMessageCompleted; client.GetMessageAsync(); } void client_GetMessageCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { if(e.Error != null) { MessageBox.Show(e.Error.Message); } }
这里值得注意的是,在异步方法执行完成后,参数e会携带WCF抛出的异常信息,保存在e.Error中。下面我们按下F5,来执行看看会发生什么,如图:
public class SilverlightFaultBehavior : Attribute, IServiceBehavior { private class SilverlightFaultEndpointBehavior : IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new SilverlightFaultMessageInspector()); } public void Validate(ServiceEndpoint endpoint) { } private class SilverlightFaultMessageInspector : IDispatchMessageInspector { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { return null; } public void BeforeSendReply(ref Message reply, object correlationState) { if ((reply != null) && reply.IsFault) { HttpResponseMessageProperty property = new HttpResponseMessageProperty(); property.StatusCode = HttpStatusCode.OK; reply.Properties[HttpResponseMessageProperty.Name] = property; } } } } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints) { endpoint.Behaviors.Add(new SilverlightFaultEndpointBehavior()); } } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } }
View Code
然后,修改UserService的代码如下:
然后,我们在UserService上面,点击鼠标右键,在浏览器中预览一下,然后再客户端上的UserServiceReference上面,点击右键,更新服务引用,然后我们按Ctrl + F5,以release模式运行项目(这样不会中断),如图:
我们看到,这次显示了不同的错误,但是依然没有抛出真正的异常信息,我们还是不知道哪里出现错了。不过根据提示消息,我们可以看到解决办法,然后打开webConfig,寻找includeExceptionDetailInFaults,果然有这个配置,如图:
我们修改includeExceptionDetailInFaults的值为true,然后再执行,我们看到了如下信息:
哈哈,终于看到真正的异常信息了。
下面再来说一种方法,不修改webconfig文件,如图:
当然,我们也可以完整的将WCF的异常的抛给客户端(服务端不做任何错误处理),但是这样可能会泄露一些敏感信息,并不安全。更多关于WCF异常处理的信息,可以参考园内大牛的博客:
WCF技术剖析之二十一: WCF基本的异常处理模式[上篇]
WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
WCF技术剖析之二十一:WCF基本异常处理模式[下篇]
二、客户端的调用WCF和异常处理
下面,我们修改客户端代码,添加一个代理类,来对WCF的调用进行一些封装,关于WCF中使用回调函数,可以参考我之前的这篇博客Silverlight中异步调用WCF服务,传入回调函数,代码如下:
这里客户端的异常e.Error可以通过回调函数传递给页面,然后做处理。然后,我们修改UserService,如图:
然后,更新服务引用,我们调用这个WCF方法,加上Try...Catch...,大概就变成了下面这个样子,如图:
这时我们按下F5运行,会看到弹出了我们返回的结果:"WCF Result"。
下面我们在显示结果前加些代码,如图:
然后,F5运行,猜猜会出现什么情况,按照我们所想的,应该是弹出一个消息框,对吧,但是,实际情况是这样的,如图:
咦,为什么我们写的Try...Catch...没有捕获到异常呢?代码明明在Try...Catch...里面啊~~,到这里,我想你们应该清楚我这边博客标题的含义了吧~~
如果之前一直是这样的写的,以后就要赶紧改啦~~
其实,我们出现异常的这段代码,是通过一个Lamda表达式传进来的一个匿名委托,相当于一个独立的方法,所以这个方法根本就不在你的Try...Catch...的作用域内。(说的不对,还请指正)。
所以,将Try...Catch...写到内部就可以了,修改代码如下,就可以了,如图:
到这里,就算是说完了。这里提醒一下大家以后写代码,测试的时候一定要下断点全部走到,特别是异常处理部分。最后,祝大家工作愉快,欢迎加入QQ交流群,一起学习交流。
作者:雲霏霏
QQ交流群:243633526
博客地址:http://www.cnblogs.com/yunfeifei/
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
如果大家感觉我的博文对大家有帮助,请推荐支持一把,给我写作的动力。
相关文章推荐
- WCF基础教程之异常处理:你的Try..Catch语句真的能捕获到异常吗?
- C#异常处理-采用try、catch语句结构来捕获和处理异常
- 【C++】try 语句捕获异常,catch子句处理异常
- Java异常处理之try...catch...语句的使用进阶
- 捕获异常语句try..catch..finally..
- Java异常捕获之try...catch...finally语句
- 描述异常处理语句try、catch、finally执行时的相互关系
- try与catch异常捕获处理(说明)及案例
- Java基础知识强化之IO流笔记02:try...catch的方式处理异常
- JAVA基础再回首(十九)——异常的概述、Try…Catch、多异常处理、Throws、throw、finally、自定义异常及异常的注意事项
- try-catch-finally 规则( 异常处理语句的语法规则 )
- IOS开发之--异常处理--使用try 和 catch 来捕获错误。
- c#描述异常处理语句try、catch、finally执行时的相互关系
- Java基础教程38-异常-try-catch
- js的异常捕获try和catch语句
- python中的异常捕获处理机制(try...except...等语句)
- c#描述异常处理语句try、catch、finally执行时的相互关系
- JavaSE_43th_异常的捕获和处理(try-catch-finally)
- c#描述异常处理语句try、catch、finally执行时的相互关系
- 使用try...catch语句处理异常