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/
 

posted @ 2011-06-30 10:18 Gavin Liu 阅读(...) 评论(...) 编辑 收藏

Right people get the right information at the right time.
以技术求生存,以市场求发展;学以至用,开拓创新;达技术之颠峰,至市场之广阔!