`

WCF在同步和异常调用情况下的异常捕获

    博客分类:
  • WCF
阅读更多

WCF在同步和异常调用情况下的异常捕获

1 前言

关于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, string communCode, out CallException callException)
        {
            callException = null;
            User user = null;
            BLL.UserBLL userBll = Common.ServiceLocator.LoadService<BLL.UserBLL>();
            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<BLL.UserBLL>();
            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>(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, ref b, 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<Service1.CallException> ex)
            {
                Console.WriteLine("半?路·接ó获?CallException Error:{0},{1}", ex.Detail.Message, ex.Detail.Detail);
            }
            catch (Exception ex)
            {
                Console.WriteLine("最?后ó一?关? Error:{0},{1}", ex.Message, ex.HelpLink);
            }

            Console.Read();
        }
    }
}

 

主要是看catch (FaultException<Service1.CallException> ex) 这一句。就好像是,WCF将我们的异常信息类包装到FaultException这个类中。然后ex.Detail就是CallException这个我们自定义的实体类型了。那就可以根据这个实体的属性进行异常的处理了。

2.3 异步调用

异步调用,我们用Silverlight来模型客户端程序。

我们都知道,异步调用,其实就是多线程。然后再callback中处理返回的数据。

这时候,就会发现不能try。。。catch。。。了。因为调用成功,还是失败,是在方法完成的委托函数中才知道的。没有地方给你写try。。。catch。。。了。

  Service1.Service1Client client = new Service1.Service1Client();
  client.GetUserByIDCompleted += new EventHandler<Service1.GetUserByIDCompletedEventArgs>(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的异常的时候,是如何处理的?有更好的办法,欢迎大家一起讨论。

源码下载:/Files/virusswb/WcfDemo.zip

0
0
分享到:
评论

相关推荐

    WCF 同步 异步调用 实例

    ### 一、WCF同步调用 同步调用是程序执行的默认方式,它会阻塞调用线程,直到服务端返回响应。在WCF中,同步调用通过调用服务接口的方法直接完成。以下是一段简单的同步调用示例: ```csharp using (Service...

    silverlight学习之路(2)异步编程趋于同步 利用async和await调用wcf服务

    异步操作可能引发异常,因此通常需要在`try-catch`块中进行捕获和处理。另外,由于异步任务可能在未来的某个时刻完成,所以必须确保服务代理实例在其生命周期内有效,或者使用`using`语句确保在不再需要时正确关闭和...

    Silverlight异步调用WCF接口(非常简单易懂)

    在调用WCF服务时,使用异步模式能显著提高应用性能和用户体验。 4. **创建WCF服务** - 首先,创建一个新的WCF服务项目,在服务接口中定义操作合同(OperationContract)。 - 接下来,实现这些合同,确保服务的...

    Synchronous_Silverlight与WCF同步操作

    5. **处理异常**:同步调用可能会抛出异常,因此在调用服务方法后,通常需要包含异常处理代码,以捕获和处理可能出现的问题。 6. **回调和状态管理**:在同步操作中,由于调用是阻塞的,所以通常不需要显式的回调...

    C#通过WCF文件分段上传

    9. **错误处理和异常管理**:在分段上传过程中,可能会遇到网络中断、服务不可用等问题,因此需要在客户端和服务端都进行适当的错误处理和异常捕获。 10. **状态管理和同步**:服务端需要跟踪每个文件的上传状态,...

    WCF学习笔记,一步一步教你学习WCF

    - 处理异常情况。 #### 五、异常处理 - **目的**:确保服务在发生错误时能够正常运行,并给出适当的反馈。 - **策略**: - 使用`FaultException`抛出错误。 - 定义自定义错误类型。 - 捕获异常并进行日志记录。...

    android wcf webservice客户端+服务器

    WCF服务可以通过配置文件来定义服务接口、绑定、行为和终结点,使得服务的部署和调用更为灵活。 在Android客户端与WCF服务的交互中,我们需要实现以下步骤: 1. **创建WCF服务**:在.NET环境中,开发人员首先需要...

    siverlight wcf ria案例下载

    8. **错误处理和异常管理**:案例中应包含适当的错误处理和异常捕获机制,确保在出现错误时能向用户友好地显示信息。 通过深入研究"Nicholas.SilverlightSellThrough"这个案例,开发者可以学习到如何将Silverlight...

    android调用.net的webservice

    在这种情况下,Android客户端需要能够调用.NET的Web服务来获取数据或执行业务逻辑。本文将深入探讨如何实现这一过程,并针对可能出现的问题提供解决方案。 首先,理解基础概念是至关重要的。Web服务是一种通过网络...

    SilverLight 4 调用RIA Service例程

    通过RIA Services,开发者可以在客户端和服务器之间轻松地同步数据,无需编写大量重复的代码。 2. **设置Silverlight项目**:首先,你需要创建一个Silverlight 4项目,并在同一个解决方案中添加一个WCF RIA ...

    几种调用WebService的方法

    3. **C#**:可以利用.NET Framework提供的`System.Web.Services.Protocols.SoapHttpClientProtocol`类或使用WCF(Windows Communication Foundation)来调用WebService。 4. **PHP**:可以使用内置的`SoapClient`类...

    基于Windows Mobile 的数据同步技术

    - **提升客户端用户体验**:即使在网络连接不稳定的情况下,也能提供快速响应和丰富的用户体验。 #### 二、远程数据访问(Remote Data Access) 远程数据访问(RDA)是一种简单而强大的技术,它使得移动设备能够...

    网络应用编程课本上实验ch02.zip

    在这个实验中,可能要求学生实现一个使用WCF服务来传输和存储用户在InkCanvas上绘制的墨迹数据的应用。这涉及到理解如何将墨迹数据序列化,通过WCF服务发送到服务器,然后在另一端反序列化并重新显示。这可能会涉及...

    yyyg源代码

    4. **异常处理**:适当的异常捕获和处理,避免程序因异常而崩溃。 5. **并行与并发**:利用多线程或多进程提高程序执行效率,但需要注意同步和竞态条件问题。 6. **代码复用**:通过函数、类或模块化设计减少重复...

    WCF和Silverlight-将您的代码全部放在一起

    由于网络延迟,直接的同步调用可能会导致用户界面冻结。因此,银光light中的WCF调用通常使用异步模式,保证UI的响应性。通过BeginXXX/EndXXX方法或async/await关键字实现异步调用。 **知识点六:身份验证和安全性**...

    RemotingV2.0

    5. **更好的异常处理**:在V2.0中,远程调用的异常处理更加完善,能够更准确地捕获和处理远程异常。 6. **安全性增强**:提供了更多的安全特性,如证书认证、消息完整性检查等,以增强网络通信的安全性。 在提供的...

    Silverlight聊天开发

    Silverlight提供了异常处理机制,开发者可以通过try-catch语句捕获和处理异常。同时,Visual Studio提供了强大的调试工具,帮助定位和修复问题。 综上所述,"Silverlight聊天开发"涉及到的技术包括Silverlight的UI...

    xml web client(2)

    XML Web服务客户端(2)是关于利用C#和ASP.NET技术高效地调用Web服务的教程。...不过,记住要根据具体需求选择合适的通信方式,如同步调用、异步调用或单向消息模式,并始终确保正确处理可能出现的异常。

    C#在VS2005_下的典型实例源码大全.rar

    此外,Windows Communication Foundation(WCF)作为统一的通信框架,也在源码中有所体现,包括服务的创建、配置和客户端调用。 八、单元测试和调试 VS2005内置的单元测试框架使得开发者可以编写测试用例来验证...

Global site tag (gtag.js) - Google Analytics