WCF 第六章 序列化和编码 使用代理序列化类型
2010-12-21 14:37 DanielWise 阅读(800) 评论(1) 编辑 收藏 举报有时你可能需要完成一个不可序列化或者需要对序列化内容进行改变的序列化过程。一个例子是由第三方组件提供者提供或者一个你不再拥有源码的组件中的一个类型。下面的例子显示了一个不可序列化的类(查看列表6.26),Employee.这个类故意不生成一个默认构造函数而且它没有任何可写的字段或属性。这意味着它不可使用任何我们到目前为止提到的序列化技术来序列化它。为了序列化这个类我们需要提供一个可以代表序列化类的代理。
列表6.26 不可序列化的Employee类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class Employee { private int employeeID; private string firstName; private string lastName; public Employee( int employeeID, string firstName, string lastName) { this .employeeID = employeeID; this .firstName = firstName; this .lastName = lastName; } public int EmployeeID { get { return employeeID; } } public string FirstName { get { return firstName; } } public string LastName { get { return lastName; } } } |
你需要两步来开发一个代理。第一步是定义代表序列化类型的数据契约。第二部是实现一个基于IDataContractSurrogate接口的数据契约代理。我们将要检查三个主要的方法是GetDataContractType, GetDeserializedObject和GetObjectToSerialize方法。GetDataContractType 给DataContractSerializer返回序列化类型,GetDeserializedObject和GetObjectToSerialize按要求执行反序列化和序列化。EmployeeSurrogate类在列表6.27中显示。
列表6.27 Employee代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | using System.Runtime.Serialization; namespace Services { [DataContract] internal class EmployeeSurrogated { [DataMember] private int employeeID; [DataMember] private string firstName; [DataMember] private string lastName; public EmployeeSurrogated( int employeeID, string firstName, string lastName) { this .employeeID = employeeID; this .firstName = firstName; this .lastName = lastName; } public int EmployeeID { get { return employeeID; } } public string FirstName { get { return firstName; } } public string LastName { get { return lastName; } } } public class EmployeeSurrogate : IDataContractSurrogate { #region IDataContractSurrogate Members public object GetCustomDataToExport(Type clrType, Type dataContractType) { return null ; //NotImplement } public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType) { return null ; //NotImplement } public Type GetDataContractType(Type type) { if ( typeof (Employee).IsAssignableFrom(type)) { return typeof (EmployeeSurrogated); } return type; } public object GetDeserializedObject( object obj, Type targetType) { if (obj is EmployeeSurrogated) { EmployeeSurrogated oldEmployee = (EmployeeSurrogated)obj; Employee newEmployee = new Employee(oldEmployee.EmployeeID, oldEmployee.FirstName, oldEmployee.LastName); return newEmployee; } return obj; } public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes) { throw new NotImplementedException(); } public object GetObjectToSerialize( object obj, Type targetType) { if (obj is Employee) { Employee oldEmployee = (Employee)obj; EmployeeSurrogated newEmployee = new EmployeeSurrogated(oldEmployee.EmployeeID, oldEmployee.FirstName, oldEmployee.LastName); return newEmployee; } return obj; } public Type GetReferencedTypeOnImport( string typeName, string typeNamespace, object customData) { if (typeNamespace.Equals( "http://schemas.datacontract.org/2004/07/EmployeeSurrogated" )) { if (typeName.Equals( "EmployeeSurrogated" )) { return typeof (Employee); } } return null ; } public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit) { return typeDeclaration; } #endregion } } |
我们通过让DataContractSerializer知道代理类来将所有内容放到一起。你需要实例化DataContractSerializer并将EmployeeSurrogated类传递给构造函数,如列表6.28显示。
列表6.28 使用DataContractSerializer的Employee代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | class Program { static void TryToSerialize(Employee e) { DataContractSerializer dcs = new DataContractSerializer( typeof (Employee)); using (StringWriter sw = new StringWriter()) { using (XmlWriter xw = XmlWriter.Create(sw)) { try { dcs.WriteObject(xw, e); } catch (InvalidDataContractException ex) { Console.WriteLine( "Cannot serialize without a surrogate! {0}" , ex.Message); } } } } static string SerializeUsingSurrogate(DataContractSerializer dcs, Employee e) { using (StringWriter sw = new StringWriter()) { using (XmlWriter xw = XmlWriter.Create(sw)) { dcs.WriteObject(xw, e); xw.Flush(); return sw.ToString(); } } } static Employee DeserializeUsingSurrogate(DataContractSerializer dcs, string employeeAsString) { using (StringReader tr = new StringReader(employeeAsString)) { using (XmlReader xr = XmlReader.Create(tr)) { return dcs.ReadObject(xr) as Employee; } } } static void Main( string [] args) { Employee e = new Employee(12345, "Daniel" , "Dong" ); TryToSerialize(e); DataContractSerializer dcs = new DataContractSerializer( typeof (Employee), null , int .MaxValue, false , false , new EmployeeSurrogate()); string employeeAsString = SerializeUsingSurrogate(dcs, e); e = DeserializeUsingSurrogate(dcs, employeeAsString); Console.ReadLine(); } } |
作者:DanielWise
出处:http://www.cnblogs.com/danielWise/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述