C# 使用JSON序列化多个不同类型的对象
我有两个从抽象类继承的类C# 使用JSON序列化多个不同类型的对象,c#,json,serialization,types,C#,Json,Serialization,Types,我有两个从抽象类继承的类 public class Class1 : MainBaseClass { public int attrib1 {get; set;} public int attrib2 {get; set;} } public class Class2 : MainBaseClass { public int attribx {get; set;} public int attriby {get; set;} } 然后我创建了一个MainBaseCla
public class Class1 : MainBaseClass
{
public int attrib1 {get; set;}
public int attrib2 {get; set;}
}
public class Class2 : MainBaseClass
{
public int attribx {get; set;}
public int attriby {get; set;}
}
然后我创建了一个MainBaseClass类型的列表,以便在一个JSON字符串中序列化这两个类,但我得到了这个异常
类型的例外
中发生“System.Runtime.Serialization.SerializationException”
System.Runtime.Serialization.dll,但未在用户代码中处理
其他信息:键入“MyProject.Class1”和数据协定
名称“Class1:”不是
预期。将任何静态未知的类型添加到已知类型列表中
类型-例如,通过使用KnownTypeAttribute属性或
将它们添加到传递给的已知类型列表中
DataContractSerializer
我的方法是:
Class1 class1 = getData();
Class2 class2 = getData();
Package<MainBaseClass> package = new Package<MainBaseClass>();
package.AddObject(class1)
package.AddObject(class2);
//Here's the error
new ServiceClass().Serialize<Package<MainBaseClass>>(package);
Class1=getData();
Class2 Class2=getData();
包=新包();
package.AddObject(class1)
package.AddObject(class2);
//这是错误
新ServiceClass().序列化(包);
我的套餐课
public class Package<T>
{
public List<T> Objects = new List<T>();
public Package() { }
public void AddObject(T dto)
{
this.Objects.Add(dto);
}
}
公共类包
{
公共列表对象=新列表();
公共包(){}
公共无效添加对象(T dto)
{
this.Objects.Add(dto);
}
}
我的序列化程序方法
public static string Serialize<T>(T entity)
{
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
//Here's the exception
ser.WriteObject(stream, entity);
stream.Position = 0;
StreamReader sr = new StreamReader(stream);
return sr.ReadToEnd();
}
公共静态字符串序列化(T实体)
{
MemoryStream stream=新的MemoryStream();
DataContractJsonSerializer ser=新的DataContractJsonSerializer(类型(T));
//这是个例外
ser.WriteObject(流、实体);
流位置=0;
StreamReader sr=新的StreamReader(流);
返回sr.ReadToEnd();
}
我还在MainBaseClass和子类上添加了[DataContract()],异常仍然存在
只有这样做,才能从基类和子类中删除[DataContract()]。如果不是,我将以空字符串“{}”的形式接收结果
Class1=getData();
包=新包();
package.AddObject(class1)
string str=new ServiceClass().Serialize(包);
或者这个:
Class1 class1 = getData();
string str = new ServiceClass().Serialize<Class1>(class1);
Class1=getData();
string str=new ServiceClass().Serialize(class1);
那么,如何序列化不同类型的多个对象呢?我明白了。唯一要做的就是只在主基类上添加DataContract属性
[DataContract()]
public class MainBaseClass {}
然后,在每个子类上,我们需要添加KnownType属性
[KnownType(typeof(Class1))]
public class Class1 : MainBaseClass
{
}
[KnownType(typeof(Class2))]
public class Class2 : MainBaseClass
{
}
就这样!这解决了我最初的问题。我明白了。唯一要做的就是只在主基类上添加DataContract属性
[DataContract()]
public class MainBaseClass {}
然后,在每个子类上,我们需要添加KnownType属性
[KnownType(typeof(Class1))]
public class Class1 : MainBaseClass
{
}
[KnownType(typeof(Class2))]
public class Class2 : MainBaseClass
{
}
就这样!这解决了我最初的问题。如果要使用,则需要用属性修饰MainBaseClass
,以便在编译时通知序列化程序所有可能的派生类型。此要求在以下文件中进行了说明:和:
完成此操作后,将为值为“DataContractName:DataContractNamespace”的类型为MainBaseClass
的多态字段发出一个额外的JSON属性“\uuuU type”。此语法是JSON标准的.Net扩展,并提示以后反序列化时使用哪种具体类型。因此,如果您的包
类看起来像:
[DataContract]
public class Package<T>
{
[DataMember]
public List<T> Objects = new List<T>();
public Package() { }
public void AddObject(T dto)
{
this.Objects.Add(dto);
}
}
如果您不希望这样,在.Net 4.5及更高版本中,可以通过设置为以下值来抑制带有DataContractJsonSerializer
的类型信息输出:
但是,如果没有类型信息,您将无法稍后使用DataContractJsonSerializer
反序列化JSON
作为替代,您可以考虑使用JSON.NET,它不需要对序列化的所有可能派生类型都有超前的知识。请参见此处:了解详细信息。
如果要使用,则需要使用属性修饰MainBaseClass
,以在编译时通知序列化程序所有可能的派生类型。此要求在以下文件中进行了说明:和:
完成此操作后,将为值为“DataContractName:DataContractNamespace”的类型为MainBaseClass
的多态字段发出一个额外的JSON属性“\uuuU type”。此语法是JSON标准的.Net扩展,并提示以后反序列化时使用哪种具体类型。因此,如果您的包
类看起来像:
[DataContract]
public class Package<T>
{
[DataMember]
public List<T> Objects = new List<T>();
public Package() { }
public void AddObject(T dto)
{
this.Objects.Add(dto);
}
}
如果您不希望这样,在.Net 4.5及更高版本中,可以通过设置为以下值来抑制带有DataContractJsonSerializer
的类型信息输出:
但是,如果没有类型信息,您将无法稍后使用DataContractJsonSerializer
反序列化JSON
作为替代,您可以考虑使用JSON.NET,它不需要对序列化的所有可能派生类型都有超前的知识。请参见此处:了解详细信息。
您尝试过吗?因此,如果我理解,这将是.net framework的一个限制?为什么它根本不起作用?同时,我将审查你的建议。谢谢。你试过了吗?所以,如果我理解的话,这将是.net框架的一个限制?为什么它根本不起作用?同时,我将审查你的建议。谢谢var settings = new DataContractJsonSerializerSettings { EmitTypeInformation = EmitTypeInformation.Never };