zoukankan      html  css  js  c++  java
  • WCF 学习笔记之异常处理

    WCF 学习笔记之异常处理

    1:WCF异常在配置文件

    复制代码
    <configuration>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="serviceDebuBehavior">
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <services>      
          <service name="Artech.WcfServices.Service.CalculatorService" behaviorConfiguration="serviceDebuBehavior">
            <endpoint address="http://127.0.0.1:3721/calculatorservice"
                      binding="ws2007HttpBinding"
                      contract="Artech.WcfServices.Service.Interface.ICalculator" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    复制代码


    2:也可以直接在服务上直接用特性进行设定

    [ServiceBehavior(IncludeExceptionDetailInFaults=true)]

    public class CalculatorService:ICalculator

    {

    }

    上面两种方式实现的效果是一样的;

    3:自定义异常信息

      (1)直接通过FaultException直接指定错误的信息

    复制代码
    using System.ServiceModel;
    namespace Artech.WcfServices.Service
    {
        public class CalculatorService : ICalculator
        {
            public int Divide(int x, int y)
            {
                if (0 == y)
                {
                    throw new FaultException("被除数y不能为零!");
                }
                return x / y;
    
            }
        }
    }
    复制代码

      相应的配置文件内容为:

    复制代码
    <configuration>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="serviceDebuBehavior">
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <services>      
          <service name="Artech.WcfServices.Service.CalculatorService" behaviorConfiguration="serviceDebuBehavior">
            <endpoint address="http://127.0.0.1:3721/calculatorservice"
                      binding="ws2007HttpBinding"
                      contract="Artech.WcfServices.Service.Interface.ICalculator" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    复制代码

    (2)通过FaultException<TDetail>采用自定义类型封装错误

    首先我们看一下一个实例;注意Interface层里的CalculaltionError.cs这个是自定义封装的错误类;

    CalculaltionError.cs类代码如下:它是一个数据契约

    复制代码
    using System.Text;
    using System.Runtime.Serialization;
    
    namespace Artech.WcfServices.Service.Interface
    {
        [DataContract]
        public class CalculationError
        {
            public CalculationError(string operation, string message)
            {
                this.Operation = operation;
                this.Message = message;
            }
            [DataMember]
            public string Operation { get; set; }
            [DataMember]
            public string Message { get; set; }
        }
    
    }
    复制代码

    契约里的定义如下:为了确保错误细节对象能够被正常序列化和反序列化,要按照如下的方式通过FaultContractAttribute特性为操作定义基于CalculationError类型的错误契约(错误契约的一些注意点在下面会讲到);

    复制代码
    namespace Artech.WcfServices.Service.Interface
    {
        [ServiceContract(Namespace = "http://www.artech.com/")]
        public interface ICalculator
        {
            [OperationContract]
            [FaultContract(typeof(CalculationError))]
            int Divide(int x, int y);
        }   
    }
    复制代码


    服务实现里直接抛出一个FaultException<CalculationError>,并创建一个CalculationError对象作为该异常对象的细节;

    复制代码
    using System.ServiceModel;
    namespace Artech.WcfServices.Service
    {
        public class CalculatorService : ICalculator
        {
            public int Divide(int x, int y)
            {
                if (0 == y)
                {
                    var error = new CalculationError("Divide", "被除数y不能为零!");
                    throw new FaultException<CalculationError>(error, error.Message);
                }
                return x / y;
            }
        }
    }
    复制代码

    服务实现的配置文件内容如下:

    复制代码
    <configuration>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="serviceDebuBehavior">
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <services>      
          <service name="Artech.WcfServices.Service.CalculatorService" behaviorConfiguration="serviceDebuBehavior">
            <endpoint address="http://127.0.0.1:3721/calculatorservice"
                      binding="ws2007HttpBinding"
                      contract="Artech.WcfServices.Service.Interface.ICalculator" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    复制代码

    客户端调用相关的异常处理;获得FaultException<CalculationError>类型的异常

    复制代码
    using System.ServiceModel;
    using Artech.WcfServices.Service.Interface;
    namespace Artech.WcfServices.Clients
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
                {
                    ICalculator calculator = channelFactory.CreateChannel();
                    using (calculator as IDisposable)
                    {
                        try
                        {
                            int result = calculator.Divide(1, 0);
                        }
                        catch (FaultException<CalculationError> ex)
                        {
                            Console.WriteLine("运算错误");
                            Console.WriteLine("运算操作:{0}", ex.Detail.Operation);
                            Console.WriteLine("错误消息: {0}", ex.Detail.Message);
                            (calculator as ICommunicationObject).Abort();
                        }
                    }                
                }
                Console.Read();
    
            }
        }
    
    }
    复制代码

    客户端配置信息如下:

    复制代码
    <configuration>
      <system.serviceModel>
        <client>
          <endpoint name="calculatorservice"
                    address= "http://127.0.0.1:3721/calculatorservice"
                    binding="ws2007HttpBinding"
                    contract="Artech.WcfServices.Service.Interface.ICalculator"/>
        </client>
      </system.serviceModel>
    </configuration>
    复制代码


    *接下来讲解关于错误契约的注意点:

    对于错误契约的运用不仅仅在将自定义的错误细节类型应用到服务契约相应操作上时才要显式地在操作方法上应用FaultContracAttribute特性;对于一些基元类型(比如Int32, String等)也要这么做;

    复制代码
        public class CalculatorService : ICalculator
        {
            public int Divide(int x, int y)
            {
                if (0 == y)
                {
                    throw new FaultException<String>("不能为0");
                }
                return x / y;
            }
        }
    复制代码

    契约如下:

    复制代码
    namespace Artech.WcfServices.Service.Interface
    {
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            [FaultContract(typeof(string))]
            int Divide(int x, int y);
        }   
    }
    复制代码

    当然它是可以多次声明针对多个异常的处理

    复制代码
    namespace Artech.WcfServices.Service.Interface
    {
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            [FaultContract(typeof(CalculationError))]
            [FaultContract(typeof(string))]
            int Divide(int x, int y);
        }   
    }
    复制代码


    若是两个是相同类型的则要增加Name 或者Namespace来区别开;若是Name一样类型不一样同样会报错;

    复制代码
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            [FaultContract(typeof(CalculationError),Name="CalualationError")]
            [FaultContract(typeof(CalculationError),Name="CalualationException")]
            int Divide(int x, int y);
        }   
    复制代码


    (4)通过XmlSerializer对错误细节对象进行序列化([XmlSerializerFormat(SupportFaults=true)])因为WCF默认是采用序列化器是DataContractSerializer(WCF提供的两种序列化器DataContractSerializer 和 XmlSerializer)

    复制代码
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            [FaultContract(typeof(CalculationError))]
            [XmlSerializerFormat(SupportFaults=true)]
            int Divide(int x, int y);
        }   
    复制代码

    封装的错误类如下:

    复制代码
        [Serializable]
        public class CalculationError
        {
            [XmlAttributeAttribute("op")]
            public string Operation { get; set; }
            [XmlElement("Error")]
            public string Message { get; set; }
        }
    复制代码
     
     
     
    标签: WCF
  • 相关阅读:
    2015/12/14 Python网络编程,TCP/IP客户端和服务器初探
    2015/12/12 考了PAT,又回来玩Python了。
    2015/11/9用Python写游戏,pygame入门(8):按钮和游戏结束
    2015/11/7用Python写游戏,pygame入门(7):碰撞检测
    2015/11/6用Python写游戏,pygame入门(6):控制大量的对象
    2015/11/5用Python写游戏,pygame入门(5):面向对象的游戏设计
    2015/11/4用Python写游戏,pygame入门(4):获取鼠标的位置及运动
    联奕公司奕报告集成数据库权限分配
    分享泛微公司OA系统用于二次开发的sql脚本
    (项目积累的)SQL数据库点滴
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3181152.html
Copyright © 2011-2022 走看看