首页 > 代码库 > System.Runtime.Serialization.SerializationException”类型的未经处理的异常在 System.Runtime.Serialization.dll 中发生

System.Runtime.Serialization.SerializationException”类型的未经处理的异常在 System.Runtime.Serialization.dll 中发生

异常信息:

“System.Runtime.Serialization.SerializationException”类型的未经处理的异常在 System.Runtime.Serialization.dll 中发生

其他信息: 不应为数据协定名称为“Teacher:http://schemas.datacontract.org/2004/07/ConsoleApplication3”的类型“ConsoleApplication3.Teacher”。请考虑使用 DataContractResolver,或将任何未知类型以静态方式添加到已知类型的列表。例如,可以使用 KnownTypeAttribute 特性,或者将未知类型添加到传递给 DataContractSerializer 的已知类型列表。

 

想要序列化的对象:

1     public class Student : People2     {3         public Int32 Age { get; set; }4     }
1     public abstract class People2     {3         public string Name { get; set; }4         public string Address { get; set; }5     }

序列化的方法:

1         public static string WriteJson<T>(T t)2         {3             using (MemoryStream ms = new MemoryStream())4             {5                 DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));6                 serializer.WriteObject(ms, t);7                 return Encoding.UTF8.GetString(ms.ToArray());8             }9         }

方法调用:

1             People p = new Student()2             {3                 Name = "小明",4                 Address = "章丘路110号",5                 Age = 146             };7 8             string jsonString = WriteJson<People>(p);9             Console.WriteLine(jsonString);

然后就有了上面的异常

根据异常可以知道,虽然Student继承了People类,但是序列化的时候是People类型,也就是说序列化的时候并不知道 想要序列化的对象(Student类型),故产生了异常;根据异常提示,有两种解决方案:考虑使用 DataContractResolver,或将任何未知类型以静态方式添加到已知类型的列表。

经过了MSDN一番查询后,得到了两种可以序列化继承关系的对象的方法,

方式一,继承DataContractResolver类来实现:

 1     public abstract class Animal 2     { 3         public string Name { get; set; } 4     } 5  6     public class Bird : Animal 7     { 8         public string Color { get; set; } 9         public Feather BDeather { get; set; }10     }11 12     public class Feather13     {14         public string Color { get; set; }15     }
 1         public static string WriteJson<T>(T t) 2         { 3             using (MemoryStream ms = new MemoryStream()) 4             { 5                 Assembly assembly = Assembly.Load(new AssemblyName("ConsoleApplication3")); 6                 DataContractSerializer serializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null, new MyDataContractResolver(assembly)); 7                 serializer.WriteObject(ms, t); 8                 return Encoding.UTF8.GetString(ms.ToArray()); 9             }10         }
1             Animal animal = new Bird()2             {3                 Name = "鸭子",4                 Color = "白色",5                 BDeather = new Feather() { Color="纯白色"}6             };7             string jsonString = WriteJson<Animal>(animal);8             Console.WriteLine(jsonString);
 1     public class MyDataContractResolver : DataContractResolver 2     { 3        4         private XmlDictionary dictionary = new XmlDictionary(); 5         Assembly assembly; 6         public MyDataContractResolver(Assembly assembly) 7         { 8             this.assembly = assembly; 9         }10         public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)11         {12             Type type = knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, knownTypeResolver);13             if (type == null)14             {15                 type = Type.GetType(typeName + ", " + typeNamespace);16             }17             return type;18         }19 20         public override bool TryResolveType(Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)21         {22             knownTypeResolver.TryResolveType(type, declaredType, knownTypeResolver, out typeName, out typeNamespace);23             if (typeName == null || typeNamespace == null)24             {25                 XmlDictionary dictionary = new XmlDictionary();26                 typeName = dictionary.Add(type.FullName);27                 typeNamespace = dictionary.Add(type.Assembly.FullName);28             }29             return true;30         }31     }
View Code

输出结果:

方式二,通过KnownTypeAttribute添加识别类型:

 1     [KnownType(typeof(Student))] 2     [KnownType(typeof(Teacher))] 3     [KnownType(typeof(Pupil))] 4     [DataContract] 5     public abstract class People 6     { 7         [DataMember] 8         public string Name { get; set; } 9         [DataMember]10         public string Address { get; set; }11     }
 1     public class Student : People 2     { 3        4         public Int32 Age { get; set; } 5     } 6  7     public class Pupil : Student 8     { 9 10     }
 1     public class Teacher : People 2     { 3         public Course T_course { get; set; } 4     } 5  6    public class Course 7     { 8        public string Name { get; set; } 9        public int Times { get; set; }10     }

输出结果:

关于更详细的描述,请参考以下MSDN的内容:

http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.knowntypeattribute.aspx

http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.datacontractserializer%28v=vs.110%29.aspx

System.Runtime.Serialization.SerializationException”类型的未经处理的异常在 System.Runtime.Serialization.dll 中发生