zoukankan      html  css  js  c++  java
  • WCF 第六章 序列化和编码 使用代理序列化类型

    有时你可能需要完成一个不可序列化或者需要对序列化内容进行改变的序列化过程。一个例子是由第三方组件提供者提供或者一个你不再拥有源码的组件中的 一个类型。下面的例子显示了一个不可序列化的类(查看列表6.26),Employee.这个类故意不生成一个默认构造函数而且它没有任何可写的字段或属 性。这意味着它不可使用任何我们到目前为止提到的序列化技术来序列化它。为了序列化这个类我们需要提供一个可以代表序列化类的代理。

    列表6.26 不可序列化的Employee类

    01public class Employee
    02    {
    03        private int employeeID;
    04        private string firstName;
    05        private string lastName;
    06 
    07        public Employee(int employeeID, string firstName, string lastName)
    08        {
    09            this.employeeID = employeeID;
    10            this.firstName = firstName;
    11            this.lastName = lastName;
    12        }
    13 
    14        public int EmployeeID
    15        {
    16            get { return employeeID; }
    17        }
    18 
    19        public string FirstName
    20        {
    21            get { return firstName; }
    22        }
    23 
    24        public string LastName
    25        {
    26            get { return lastName; }
    27        }
    28    }

      你需要两步来开发一个代理。第一步是定义代表序列化类型的数据契约。第二部是实现一个基于IDataContractSurrogate接口的数据契约代 理。我们将要检查三个主要的方法是GetDataContractType, GetDeserializedObject和GetObjectToSerialize方法。GetDataContractType 给DataContractSerializer返回序列化类型,GetDeserializedObject和 GetObjectToSerialize按要求执行反序列化和序列化。EmployeeSurrogate类在列表6.27中显示。

    列表6.27 Employee代理类

    001using System.Runtime.Serialization;
    002 
    003namespace Services
    004{
    005    [DataContract]
    006    internal class EmployeeSurrogated
    007    {
    008        [DataMember]
    009        private int employeeID;
    010        [DataMember]
    011        private string firstName;
    012        [DataMember]
    013        private string lastName;
    014 
    015        public EmployeeSurrogated(int employeeID, string firstName, string lastName)
    016        {
    017            this.employeeID = employeeID;
    018            this.firstName = firstName;
    019            this.lastName = lastName;
    020        }
    021 
    022        public int EmployeeID
    023        {
    024            get { return employeeID; }
    025        }
    026 
    027        public string FirstName
    028        {
    029            get { return firstName; }
    030        }
    031 
    032        public string LastName
    033        {
    034            get { return lastName; }
    035        }
    036    }
    037 
    038    public class EmployeeSurrogate : IDataContractSurrogate
    039    {
    040        #region IDataContractSurrogate Members
    041 
    042        public object GetCustomDataToExport(Type clrType, Type dataContractType)
    043        {
    044            return null; //NotImplement
    045        }
    046 
    047        public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
    048        {
    049            return null; //NotImplement
    050        }
    051 
    052        public Type GetDataContractType(Type type)
    053        {
    054            if (typeof(Employee).IsAssignableFrom(type))
    055            {
    056                return typeof(EmployeeSurrogated);
    057            }
    058            return type;
    059        }
    060 
    061        public object GetDeserializedObject(object obj, Type targetType)
    062        {
    063            if (obj is EmployeeSurrogated)
    064            {
    065                EmployeeSurrogated oldEmployee = (EmployeeSurrogated)obj;
    066                Employee newEmployee = new Employee(oldEmployee.EmployeeID, oldEmployee.FirstName, oldEmployee.LastName);
    067                return newEmployee;
    068            }
    069            return obj;
    070        }
    071 
    072        public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes)
    073        {
    074            throw new NotImplementedException();
    075        }
    076 
    077        public object GetObjectToSerialize(object obj, Type targetType)
    078        {
    079            if (obj is Employee)
    080            {
    081                Employee oldEmployee = (Employee)obj;
    082                EmployeeSurrogated newEmployee = new EmployeeSurrogated(oldEmployee.EmployeeID, oldEmployee.FirstName, oldEmployee.LastName);
    083                return newEmployee;
    084            }
    085            return obj;
    086        }
    087 
    088        public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
    089        {
    090            if (typeNamespace.Equals("http://schemas.datacontract.org/2004/07/EmployeeSurrogated"))
    091            {
    092                if (typeName.Equals("EmployeeSurrogated"))
    093                {
    094                    return typeof(Employee);
    095                }
    096            }
    097            return null;
    098        }
    099 
    100        public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
    101        {
    102            return typeDeclaration;
    103        }
    104 
    105        #endregion
    106    }
    107}

      我们通过让DataContractSerializer知道代理类来将所有内容放到一起。你需要实例化DataContractSerializer并将EmployeeSurrogated类传递给构造函数,如列表6.28显示。

    列表6.28 使用DataContractSerializer的Employee代理类

    01class Program
    02{
    03    static void TryToSerialize(Employee e)
    04    {
    05        DataContractSerializer dcs = new DataContractSerializer(typeof(Employee));
    06        using (StringWriter sw = new StringWriter())
    07        {
    08            using (XmlWriter xw = XmlWriter.Create(sw))
    09            {
    10                try
    11                {
    12                    dcs.WriteObject(xw, e);
    13                }
    14                catch(InvalidDataContractException ex)
    15                {
    16                    Console.WriteLine("Cannot serialize without a surrogate! {0}", ex.Message);
    17                }
    18            }
    19        }
    20    }
    21 
    22    static string SerializeUsingSurrogate(DataContractSerializer dcs, Employee e)
    23    {
    24        using (StringWriter sw = new StringWriter())
    25        {
    26            using (XmlWriter xw = XmlWriter.Create(sw))
    27            {
    28                dcs.WriteObject(xw, e);
    29                xw.Flush();
    30                return sw.ToString();
    31            }
    32        }
    33    }
    34 
    35    static Employee DeserializeUsingSurrogate(DataContractSerializer dcs, string employeeAsString)
    36    {
    37        using (StringReader tr = new StringReader(employeeAsString))
    38        {
    39            using (XmlReader xr = XmlReader.Create(tr))
    40            {
    41                return dcs.ReadObject(xr) as Employee;
    42            }
    43        }
    44    }
    45 
    46    static void Main(string[] args)
    47    {
    48        Employee e = new Employee(12345, "Daniel", "Dong");
    49 
    50        TryToSerialize(e);
    51 
    52        DataContractSerializer dcs = new DataContractSerializer(typeof(Employee),
    53            null, int.MaxValue, false, false, new EmployeeSurrogate());
    54 
    55        string employeeAsString = SerializeUsingSurrogate(dcs, e);
    56 
    57        e = DeserializeUsingSurrogate(dcs, employeeAsString);
    58 
    59        Console.ReadLine();
    60    }
    61}


    =======
    转载自
    作者:DanielWise
    出处:http://www.cnblogs.com/danielWise/
     

  • 相关阅读:
    flutter canvas 简单绘画直线
    Yapi 部署及遇到的坑
    flutter 时间选择器第三方插件返回时间格式说明
    windows + flutter + vscode 连接其他模拟器
    flutter 配置环境
    flutter 返回键监听
    flutter 自定义主题切换
    flutter Provide 状态管理篇
    flutter 本地存储 (shared_preferences)
    JS做倒计时的例题
  • 原文地址:https://www.cnblogs.com/llbofchina/p/2094159.html
Copyright © 2011-2022 走看看