• 【WCF】错误处理(二):错误码―—FaultCode


    先来说说SOAP消息中错误消息的包装结构,一条SOAP错误消息的大致形式如下:

        <s:Fault>
          <faultcode xmlns:a="me-cust-error">a:错误码</faultcode>
          <faultstring xml:lang="zh-CN">错误内容</faultstring>
    ……
    </s:Fault>

    首先是Fault元素,然后下面是错误消息相关联的子元素。在上一篇烂文中,老周曾介绍过FaultReason,这个类用于包装错误文本信息,并且支持多种语言。上面所展示的Fault元素中,faultstring子元素中的内容就是FaultReason类所指定的文本。

    大伙伴们可能已经发现了,Fault元素下还有一个叫 faultcode 的子元素,它便是本文的主角,我们可以直接“望文生义”地将其翻译为错误码。错误码是干吗的?大伙应该知道 HTTP 中的错误代码,如我们经常看到的 404- not found,道理也是一样的, SOAP 消息中的错误码就是用来对某一类错误进行标识的,通常用一些简洁的短语,以便于识别。比如,一个错误命名为(错误码)RPTooLow,你一看到这条错误,就知道是因为用户的人品太差而导致操作失败。

    Fault code的命名就是一个字符串,你可以自己来取,当然应当取一些有意义的名字,不能只有你自己看得懂而别人摸不着头脑,除非你的应用程序不打算对外公开错误信息。

    在 WCF 中,可以用 FaultCode 类来定义错误码,然后把该类的实例传递给 FaultException 的构造函数就 OK 了。 

    下面老周举一个例子,假设有一个服务,它的功能是计算一个整数值的平方。其服务协定声明如下。

        [ServiceContract]
        public interface IDemo
        {
            [OperationContract]
            int Sqr(int n);
        }

    然后实现这个服务协定。

        class DemoService : IDemo
        {
            public int Sqr(int n)
            {
                if (n <= 0)
                {
                    FaultCode code = new FaultCode("ArgErr", "me-cust-error");
                    FaultReason reason = new FaultReason("传入的参数必须大于0。");
                    throw new FaultException(reason, code);
                }
                return n * n;
            }
        }

    在上面的代码中,注意 Sqr 方法,在方法里面对传入的参数进行一下验证,以确保值是大于0的。要是值不符合要求,就会抛出异常。

    在抛出异常的时候,用 FaultCode 来定义一个错误码,构造函数的第一个参数是错误码的名字,第二个参数是XML命名空间,这个也是可以自己定义的。

    下面,咱们调用一下这个服务,并故意传一个错误的参数,以便可以捕捉到异常。

                ChannelFactory<IDemo> fac = new ChannelFactory<IDemo>(binding, new EndpointAddress(svaddr));
                fac.Endpoint.EndpointBehaviors.Add(new MyEndpointBehavior());
                IDemo channel = fac.CreateChannel();
                try
                {
                    int res = channel.Sqr(-5);
                    Console.WriteLine("计算结果:{0}", res);
                }
                catch (FaultException fex)
                {
                    FaultReason reason = fex.Reason;
                    FaultReasonText rtext = reason.GetMatchingTranslation();
                    FaultCode code = fex.Code;
                    string errmsg = $"
    错误:{rtext.Text}
    错误代码:{code.Namespace}:{code.Name}";
                    Console.WriteLine(errmsg);
                }
                finally
                {
                    fac.Close();
                }

    这段代码不是很复杂,应该不用我多解释了,重点是捕捉的异常类型应当为 FaultException ,这个老周在上一篇文章中说过的。

    运行的结果如下图所示。

    示例代码下载地址:点击下载

    这篇文章老周是坐在屋顶上用 Surface 敲出来的。老周本来是拿着葫芦丝到房顶上娱乐一下,吹奏了几首曲子后,就打开 Surface 上上网,一时兴起,就写了本篇博客。

  • 相关阅读:
    CMDB服务器管理系统【s5day92】:服务器管理回顾
    主机管理+堡垒机系统开发:需求讨论(一)
    saltstack主机管理项目:今日总结(六)
    saltstack主机管理项目:动态调用插件解析-模块解析(五)
    saltstack主机管理项目:编写插件基类-获取主机列表-提取yaml配置文件(四)
    saltstack主机管理项目:计主机管理项目命令分发器(三)
    saltstack主机管理项目:主机管理项目需求分析(一)
    saltstack主机管理项目:主机管理项目架构设计(二)
    CMDB服务器管理系统【s5day89】:采集资产之整合资产
    CMDB服务器管理系统【s5day89】:采集资产之汇报信息
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/6575127.html
Copyright © 2020-2023  润新知