WCF 第六章 序列化和编码 使用代理序列化类型

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

列表6.26 不可序列化的Employee类

01 public 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代理类

001 using System.Runtime.Serialization;
002  
003 namespace 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 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代理类

01 class 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/
 

转载于:https://www.cnblogs.com/llbofchina/archive/2011/06/30/2094159.html

你可能感兴趣的:(WCF 第六章 序列化和编码 使用代理序列化类型)