• wcf契约版本处理与异常处理(随记)


    -----------版本控制策略;必须支持向后兼容;----就是当服务端发生改变,但客户端未更新会不会发生错误;

    一旦契约发布,若要契约发生变化,如何不影响客户端使用;

    ----wsdl:契约;

    服务契约的变化--对客户端的影响:

    操作签名的增加 (无影响,默认缺省值)

    操作签名的删除(无影响,默认被忽略掉)

    增加新的操作(无影响,客户端不知道)

    删除操作、修改参数类型、修改返回值(报错)

    ---

    数据契约的变化    对客户端的影响

    添加non-required   无影响;

    添加新的required   会报错;

    删除 non-required  不会报错 但会丢失;

    删除required        会报错;

    修改数据类型;      如果类型兼容,会产生未知异常,否则报错;

    解决版本兼容性;

    ----Iextensibledataobject是将冗杂的数据进行临时的保存;

     public class DataUser:IExtensibleDataObject

    {

           private ExtensionDataObject obj;

           public ExtensionDataObject ExtensionData

           {

               get

               {

                   return obj;

               }

               set

               {

                   obj = value;

               }

           }

    }

    ----数据契约序列化器;测试新旧版本兼容;

    1.using System.Runtime.Serialization;

    2.          Person p = new Person();

                p.Name = "郭泽峰";

                DataContractSerializer ds = new DataContractSerializer(typeof(Person));

                FileStream fs = new FileStream("cc.xml", FileMode.Create);

                ds.WriteObject(fs, p);

                fs.Close();

      public partial class Form1 : Form

        {

            public Form1()

            {

                InitializeComponent();

            }

            private void button1_Click(object sender, EventArgs e)

            {

                Person1 p = new Person1();

                p.Name = "d";

                p.Id = 123;

                DataContractSerializer ds = new DataContractSerializer(typeof(Person1));

                FileStream fs = new FileStream("cc.xml", FileMode.Create);

                ds.WriteObject(fs, p);

                fs.Close();

            }

            private void button2_Click(object sender, EventArgs e)

            {

                //新版本到旧版本

                DataContractSerializer ds = new DataContractSerializer(typeof(Person));

                FileStream fs = new FileStream("cc.xml",FileMode.Open);

                XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs,new XmlDictionaryReaderQuotas());

                Person per = (Person)ds.ReadObject(reader, false);

                MessageBox.Show(per.Name);

                fs.Close();

                //旧版本到新版本

                per.Name = "hhhhh";

                DataContractSerializer dss = new DataContractSerializer(typeof(Person1));

                FileStream fss = new FileStream("cc.xml", FileMode.Create);

                ds.WriteObject(fss, per);

                fss.Close();

            }

        }

    3.这样就把对象生成xml文件了;

    -----------可扩展数据对象:

    namespace wcf1

    {

        [DataContract(Name="Person", Namespace="wcf1")]

        public  class Person:IExtensibleDataObject

        {

            [DataMember]

            public string Name {get;set;}

            private ExtensionDataObject obj;

            public ExtensionDataObject ExtensionData

            {

                get

                {

                    return obj;

                }

                set

                {

                    obj = value;

                }

            }

        }

        [DataContract(Name = "Person", Namespace = "wcf1")]

        public class Person1 : IExtensibleDataObject

        {

            [DataMember]

            public string Name { get; set; }

            [DataMember]

            public int Id { get; set; }

            private ExtensionDataObject obj;

            public ExtensionDataObject ExtensionData

            {

                get

                {

                    return obj;

                }

                set

                {

                    obj = value;

                }

            }

        }

    }

    -----这样就可以实现新就版本的交互了;当然也有害处,若新版本增加了1mb数据,当提交给旧版本时,这1mb相当于没有用途;加重了负载;

    --以上是可扩展数据对象;

    禁止使用可扩展数据对象:

    <behaviors >

                                         <serviceBehaviors>

                                                   <behavior name="aa">

                                                            <dataContractSerializer ignoreExtensionDataObject="true"/>

                                                   </behavior>

                                         </serviceBehaviors>

    </behaviors>

    后者是:

      [ServiceBehavior( IgnoreExtensionDataObject=true)]

        public  class Person:IExtensibleDataObject

    ------版本控制策略:

    1.严格的版本控制,一旦改动重新生成,但是不实用;

    2.使用的版本策略:向后或向前的兼容性;

    保存未知元素和容忍缺失元素以至于可以兼容,单参数变化就不行了;

    -------

    1.添加操作,不用升级版本;

    2.删除操作,升级版本;

    3.添加了新的参数,不用升级,会默认缺省值;

    4.参数发生了变化,升级版本;

    5.删除了参数:不用升级版本;

    ----数据契约:

    1.新添加成员,不用升级;

    2.删除成员,不用升级;(多余的被忽略)

    3.数据类型,名称发生变化,需要升级;

    ---

    wcf缺省提供版本相容性支持;

    ------------------------------------------------------剖出异常:

    1.所有异常都被序列化为soap faults; (soap 1.1和soap1.2格式)

    2.soap1.2

       Code:必须;可以是规范定义的代码

       Reason:必须,错误字符串的解释信息

       Role:可选;描述错误源的URI;

       Detail:可选,提供错误的body信息;

       Node:可选;描述产生错误的节点URI;

    3. isoneway=true;标记后客户端并不能捕捉异常,而响应式则捕捉

    4. 是否包含敏感信息;

    两种方式:

    1.在wcf服务中标记:

    [ServiceBehaviorAttribute(IncluedeExceptionDetailsInFaults=true)]

    puFaultblic class service:Iservice

    {

    }

    2.web配置节点中的behavior里配置:<serviceDebug includeExceptionDetailInFaults="true">

    5.剖出类型有三种:FaultExceptionFaultException<T>MesssageFault:

      (1)

      throw new FaultException("");

      throw new FaultException(new FaultReason(""));

      throw new FaultException(new FaultReason(""),FaultCode.CreateSenderFaultCode(null));

      (2) FaultException<T>,不利于互操作,

      错误契约:[faultContract(typeof())]

    T:必须是数据契约或是可序列化类型;也可以是clr特有的异常(不利于互操作)云因如果客户端是java,和。net定义异常不一样,容易出现错误;T:为数据契约,更好的互操作;

    在契约接口的每个声明操作上添加标签;将错误信息对象化;//---案例:

    throw new FaultException<InvalidOperationException>(new InvalidOperationException(""), "", FaultCode.CreateSenderFaultCode(null));

    public interface IReturnuser

         {

             [OperationContract(IsOneWay = true)]

             [FaultContract(typeof(CusError))]

             void Return

         }

    (3) MessageFaults

    MessageFault mfault = MessageFault.CreateFault(FaultCode.CreateSenderFaultCode(null), new FaultReason("错误"), new InvalidOperationException("an error occurred"), null, "", "");

    FaultException fe = FaultException.CreateFault(mfault,typeof(InvalidOperationException));

    throw fe;

  • 相关阅读:
    Swift-基础语法之变量&常量&元组
    Swift
    安装MySQL
    LNMP 简介
    LNMP
    Django 定义数据模型
    Django 添加应用
    Django 创建第一个项目
    Django 安装
    Django 简介
  • 原文地址:https://www.cnblogs.com/guozefeng/p/3426893.html
Copyright © 2020-2023  润新知