`

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();
            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, 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 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 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

分享到:
评论

相关推荐

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

    总的来说,无论是在同步还是异步调用场景下,理解和正确处理WCF中的异常捕获是保证服务可靠性和客户端健壮性的关键。通过使用`FaultContract`,我们可以提供更详细的错误信息,使得客户端能够更有效地处理错误状况。...

    WCF 同步 异步调用 实例

    ### 二、WCF异步调用 异步调用允许客户端在等待服务响应时执行其他任务,提高应用的响应性和性能。WCF提供了两种主要的异步调用模式:基于事件的异步模式(EAP)和基于任务的异步模式(TAP)。这里我们关注基于事件...

    WCF异步调用的小例子

    **WCF异步调用详解** ...总结,WCF异步调用是优化服务性能和用户体验的重要技术,理解和掌握其工作原理对于开发高效WCF应用至关重要。通过分析提供的示例文件,你可以更好地理解并应用这些概念到实际项目中。

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

    本教程将深入讲解如何在Silverlight应用中异步调用WCF接口,以便实现高效且无阻塞的通信。 1. **Silverlight简介** Silverlight是一种插件技术,由微软开发,用于在浏览器中提供丰富的用户体验。它支持多种媒体...

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

    而本文将探讨的是如何在Silverlight应用中利用异步编程模型,特别是`async`和`await`关键字,来调用WCF(Windows Communication Foundation)服务,从而实现更高效的程序执行。 首先,让我们理解异步编程的重要性。...

    Java调用wcf服务

    - 在实际部署前,务必进行充分的单元测试和集成测试,确保Java客户端能正确调用WCF服务,并处理各种异常情况。 通过以上步骤,Java应用程序就能成功地与WCF服务进行通信,实现跨平台的数据交换。需要注意的是,...

    Synchronous_Silverlight与WCF同步操作

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

    WCF入门实例和调用天气预报

    3. **处理异常**:捕获可能出现的网络错误和业务异常,确保客户端代码健壮性。 **五、WCF高级特性** 1. **安全性**:WCF支持多种安全模式,如Transport、Message、TransportWithMessageCredential等,确保数据传输...

    C#POST请求WCF服务

    在IT行业中,C#是一种广泛使用的编程语言,尤其在开发Windows应用程序和服务方面。WCF(Windows Communication Foundation...在实际开发中,确保遵循最佳实践,如使用异步操作以提高性能,以及正确处理异常和错误情况。

    WCF文件上传和下载

    9. **错误处理和进度更新**:为了提高用户体验,可以实现异步操作,以便在文件传输过程中更新进度,同时捕获和处理可能出现的异常。 10. **性能优化**:考虑到大文件可能引发的内存问题,可以使用流处理技术分块...

    wcf基础学习

    “异步调用”(“wcf7学习之异步调用.doc”)是提高性能的关键,尤其是在处理耗时操作时。WCF提供了异步操作的支持,使得客户端可以在等待服务响应的同时进行其他工作。 “数据传输”(“wcf8学习之数据传输.doc”...

    wcf android

    7. **多线程与异步调用**:考虑到Android的UI线程不能被长时间阻塞,调用WCF服务通常会在后台线程进行,可以使用AsyncTask、IntentService或Retrofit等库来实现异步操作。 8. **Android权限管理**:由于Android系统...

    Silverlight调用WCF

    由于Silverlight的安全限制,所有的网络通信都是异步的,因此需要使用BeginXXX和EndXXX方法或者async/await关键字进行异步调用。 5. **错误处理**:处理可能出现的异常和错误是必不可少的,因为网络通信可能会失败...

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

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

    Android访问WCF服务源码(WCF服务端)

    6. **异常处理**: 在整个过程中,要捕获可能发生的异常,例如网络问题、解析错误等,并提供适当的错误处理机制。 7. **注意安全与性能**: 访问远程服务时,应考虑安全性和性能。例如,使用HTTPS协议加密传输,限制...

    WCF学习笔记(有代码有图)

    默认情况下,未捕获的异常会被转换为错误消息返回给调用者。可以自定义错误处理策略,以提供更友好的错误信息。 6. **会话状态** 会话状态允许服务跟踪和维护与客户端的交互历史。WCF支持无状态、会话状态和持久性...

    Wcf ajax c#例子

    在本文中,我们将深入探讨如何...通过这种方式,我们可以在不刷新页面的情况下,利用C#编写的WCF服务获取和更新数据,提升用户体验。在实际项目中,可能还需要考虑错误处理、数据验证、安全性和性能优化等更多细节。

    WCF 学习笔记(包括WCF基本知识、Security、MSMQ、Transaction等等)

    - **异步调用**:WCF支持异步调用模式,这对于提高服务的性能和响应性非常重要。 - **数据传输**:WCF支持多种数据格式,包括XML和二进制格式,以满足不同场景的需求。 - **端点绑定**:绑定描述了服务如何通信的...

    wcf连接数据库

    这些方法会异步调用WCF服务,等待服务返回数据或确认操作成功。 - 对于UI交互,使用回调方法处理服务调用的结果,例如显示查询结果或更新UI状态。 5. **数据库操作** - WCF服务中的数据库操作通常涉及使用ADO.NET...

    Android访问WCF服务源码(Android 客户端)

    访问WCF服务时可能会遇到网络错误、超时、解析异常等问题,因此需要在代码中进行适当的异常处理。例如,使用try-catch语句捕获`IOException`和`JSONException`,并给出相应的错误提示。 7. **性能优化** 为了提高...

Global site tag (gtag.js) - Google Analytics