Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用JSON序列化多个不同类型的对象_C#_Json_Serialization_Types - Fatal编程技术网

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 };