关于WCF的基本信息,我就不在这里介绍了。一来是因为园子中的很多人都介绍过了,而且很是详细,再不行,还可以看书。二来是因为自己的概念表达还不是很好,别误导了大家。
在这里,我就直接讲解一种用法,然后贴点代码吧。
在WCF有一种契约,叫做错误契约FaultContract。
今天我就讲解一下,在同步和异步调用WCF服务的时候,客户端如何捕获服务端抛出来的异常。捕获之后,如何处理,那就是根据项目的要求了。是提示呢?还是记录日志呢?还是其他什么的。。。。。。。。。。。。
2 正文其他对于同步和异步来说,WCF处理异常的手段是一致的。都是将异常信息,通过我们自定义的一个异常信息类,传输到客户端。客户端获取到这个类的信息,然后就知道了具体的异常。然后如何处理,就是客户端的事情了。
2.1 服务定义错误契约定义
[DataContract] public class CallException { public CallException() { } public CallException(string message,string detail) { Message = message; Detail = detail; } [DataMember] public string Message { get; set; } [DataMember] public string Detail { get; set; } }
接口定义
[ServiceContract] public interface IService1 { [OperationContract] [FaultContract(typeof(CallException))] User GetUserByID(int ID,string communCode,out CallException callException); [OperationContract] [FaultContract(typeof(CallException))] [ServiceKNownType(typeof(User ))] BaseClass.EntityBase GetByIDWithAuthentication(int ID,out CallException callException); }
接口实现
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] [Common.MyServiceBehavior()] public class Service1Impl : BaseClass.ServiceBase,IService1 { #region IService1 Members public User GetUserByID(int ID,out CallException callException) { callException = null; User user = null; BLL.UserBLL userBll = Common.ServiceLocator.LoadService(); user= userBll.GetUserByID(ID,out callException); return user; } //[Common.AuthenticationBehavior()] public BaseClass.EntityBase GetByIDWithAuthentication(int ID,out CallException callException) { callException = null; User user = null; BLL.UserBLL userBll = Common.ServiceLocator.LoadService(); user = userBll.GetByID(ID,out callException); return user; } #endregion }
业务逻辑类
public class UserBLL : BaseClass.BLLBase { public UserBLL(Common.DALHelper dalHelper) { _dalHelper = dalHelper; } private Common.DALHelper _dalHelper; [Common.ExceptionCallHandler("你?没?有瓺权ā限T","","你?没?有瓺权ā限T啊?BLL")] public User GetByID(int ID,out CallException callException) { callException = null; if (ID < 10) { callException = new CallException() { Message = "获?取?用?户§",Detail = "必?须?大洙于等台于?0" }; throw new FaultException(callException,"parameter error"); } else { User user = null; int b = 0; user = _dalHelper.UserDal.GetByID(ID,ref b,out callException); return user; } } [Common.ExceptionCallHandler("你?没?有瓺权ā限T","你?没?有瓺权ā限T啊?BLL")] public User GetUserByID(int ID,out CallException callException) { User user = null; callException = null; if (ID < 10) { callException = new CallException() { Message = "获?取?用?户§",Detail = "必?须?大洙于等台于?0" }; } else { int b = 0; user = _dalHelper.UserDal.GetByID(ID,out callException); } return user; } }
在业务逻辑类中判断参数的合法性,不合法抛出异常。大家看到有两个方法,一个是直接抛出异常,一个是没有抛出任何异常。后面将这两个的用处。
2.2 同步调用同步调用,我们用控制台程序来模拟客户端。
同步方式调用WCF的时候,我们可以直接try。。。catch。。。来捕获这个异常信息,然后进行处理。
代码如下:
using System;using System.Collections.Generic;using System.linq;using System.Text;using System.ServiceModel;using System.ServiceModel.Channels;namespace ConsoleConsumer{ class Program { static voID Main(string[] args) { Service1.Service1ClIEnt clIEnt = new Service1.Service1ClIEnt(); using (OperationContextScope scope = new OperationContextScope((IContextChannel)clIEnt.InnerChannel)) { Messageheaders messageheadersElement = OperationContext.Current.OutgoingMessageheaders; messageheadersElement.Add(Messageheader.Createheader("username","kd")); messageheadersElement.Add(Messageheader.Createheader("password","kd")); } Console.Writeline("请?输?入?ID:阰"); int ID =int.Parse ( Console.Readline()); Service1.CallException callException = null; try { clIEnt.GetByIDWithAuthentication(out callException,ID); Console.Writeline("成é功|调獭用?"); } catch (FaultException ex) { Console.Writeline("半?路·接ó获?CallException Error:{0},{1}",ex.Detail.Message,ex.Detail.Detail); } catch (Exception ex) { Console.Writeline("最?后ó一?关? Error:{0},ex.Message,ex.Helplink); } Console.Read(); } }}
主要是看catch (FaultException ex) 这一句。就好像是,WCF将我们的异常信息类包装到FaultException这个类中。然后ex.Detail就是CallException这个我们自定义的实体类型了。那就可以根据这个实体的属性进行异常的处理了。
2.3 异步调用异步调用,我们用Silverlight来模型客户端程序。
我们都知道,异步调用,其实就是多线程。然后再callback中处理返回的数据。
这时候,就会发现不能try。。。catch。。。了。因为调用成功,还是失败,是在方法完成的委托函数中才知道的。没有地方给你写try。。。catch。。。了。
Service1.Service1ClIEnt clIEnt = new Service1.Service1ClIEnt(); clIEnt.GetUserByIDCompleted += new EventHandler(clIEnt_GetUserByIDCompleted); clIEnt.GetUserByIDAsync(int.Parse(textBox1.Text.Trim()),"123456");
voID clIEnt_GetUserByIDCompleted(object sender,Service1.GetUserByIDCompletedEventArgs e){}
是通过e来获取数据的。
但是异常信息需要通过通道传递的客户端,这点和同步调用是一样的。既然这样,那我们在定义服务端方法的时候,就添加一个out类型的参数,在服务端就将CallException这个实体赋值给这个参数。然后通过e.CallException就可以获取异常信息了,如果不为空,说明有异常存在。为空,说明没有异常,访问正常。
voID clIEnt_GetUserByIDCompleted(object sender,Service1.GetUserByIDCompletedEventArgs e) { #region if (e.callException != null) { ChilDWindow win = new ChilDWindow(); win.Title = e.callException.Message; win.Content = e.callException.Detail; win.MinHeight = 50; win.MinWIDth = 200; win.Show(); } else { ChilDWindow win = new ChilDWindow(); win.Title = "ok"; win.Content = "it is ok"; win.MinHeight = 50; win.MinWIDth = 200; win.Show(); } #endregion }
3 结论
不知道大家在捕获和处理WCF的异常的时候,是如何处理的?有更好的办法,欢迎大家一起讨论。
源码下载:http://download.csdn.net/source/2785386
Technorati 标签: WCF,FaultContract(typeof(CallException)) 总结以上是内存溢出为你收集整理的WCF在同步和异步调用情况下的异常捕获全部内容,希望文章能够帮你解决WCF在同步和异步调用情况下的异常捕获所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)