【问题标题】:.Net Core Serialize an Object with IEnumerables<T> to Save as XML.Net Core 使用 IEnumerables<T> 序列化对象以另存为 XML
【发布时间】:2019-08-29 20:40:37
【问题描述】:

我正在使用 .net Core 1.1 并编写控制台应用程序。我需要使用字符串和 int 的一些基本属性以及一些 IEnumerable 对象来序列化一个对象,并将其序列化为 XML,以便将其保存到“data.xml”文件中。

我收到异常: System.Runtime.Serialization.SerializationException: 'Type 'System.Collections.Generic.List`1[[CorpsDataExtractor.ViewModels.LegacyView, CorpsDataExtractor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ArrayOfLegacyView:http://schemas.datacontract.org/2004/07/CorpsDataExtractor.ViewModels' 不是预期的。将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。'

我目前能够将我的对象序列化为 JSON,但在使用 DataContractSerializer 时遇到问题。我添加了异常状态的已知类型列表,但它仍然失败。

// This List isretrieved using Entity Framework Core
      List<LegacyView> legacyData = await _corpsRepo.ListLegacyData();

// The Below Line will write to a JSON File. No Error and works
        File.WriteAllText(@"E:\\CorporationsDataLegacy.json", JsonConvert.SerializeObject(legacyData));

// This Creates a Known Type List for the DataContractSerializer
        var knownTypeList = new List<Type>
        {
            typeof(LegacyView),
            typeof(People),
            typeof(DocumentType)
        };

        FileStream writer = new FileStream(@"E:\\data.xml", FileMode.Create);
        var ser = new DataContractSerializer(typeof(LegacyView), knownTypeList );
// When Debugging I Receive The stated exception at this line
        ser.WriteObject(writer, legacyData);

以下是我的类 ViewModel:

旧版视图

[DataContract]
public class LegacyView
{
    [DataMember]
    public string Ubi { get; set; }
    [DataMember]
    public IEnumerable<Person> People{ get; set; }
    [DataMember]
    public IEnumerable<DocumentType> DocumentTypes { get; set; }
}

人物

[DataContract]
public class Person
{ 
    [DataMember]
    public string FirstName { get; set; }
    [DataMember]
    public string MiddleName { get; set; }
}

文档

[DataContract]
public class DocumentType
{ 
    [DataMember]
    public string Document { get; set; }
    [DataMember]
    public DateTime? CompletedDate { get; set; }
}

关于我缺少什么的任何指示?

【问题讨论】:

  • 您是否尝试将typeof(IEnumerable&lt;People&gt;), typeof(IEnumerable&lt;DocumentType&gt;) 添加到已知类型?
  • @Gusman,结合使用你的答案和答案,我将我的属性保留为 IEnumerable 但是我声明了我的 KnownType List 我需要使用 List 来制作这些具体
  • 很高兴你能成功。添加您的解决方案作为答案,因为这可以帮助其他人解决您的相同问题。

标签: c# xml xml-serialization .net-core


【解决方案1】:

我可能有点偏离,因为我做了更多的 XmlSerialize 而不是 DataContracts,但我相信两者都假设最终会反序列化内容。并且使用IEnumerable&lt;T&gt; 作为类型,反序列化器将不知道在反序列化期间实际实例化哪个类来支持接口。将字段更改为具体类而不是枚举,这应该可行。

【讨论】:

  • 感谢您的意见。我将它们更改为具体类,但仍然收到相同的错误。我将添加已知类型属性并查看是否可以修复它,尽管错误状态我可以使用已知类型列表。
  • 虽然我不需要将 [Datamember] 更改为具体类,但我确实需要将已知类型列表更改为具体类所以答案是您和 Gusman 之间的组合
【解决方案2】:

通过同时使用 Gusman 和 LB2 cmets,我能够解决该问题。正如 LB2 所述,“以 IEnumerable 作为类型,反序列化器不知道在反序列化期间实际实例化哪个类来支持接口。”

这就是发生错误的原因,但问题在 Class LegacyView [DataMember] 级别不存在,它存在于被传递到 DataContractSerializer 的已知类型中。

Gusman 是正确的,我需要告诉 DataContractSerializer 这些将是可枚举类型。

// I needed to tell the DataContractSerializer what the types were
    var knownTypeList = new List<Type>
    {
        typeof(List<LegacyView>),
        typeof(List<People>),
        typeof(List<DocumentType>)
    };

    using (var writer = new FileStream(@"E:\\myTestExample.xml", FileMode.Create)) 
    {
        var ser = new DataContractSerializer(typeof(LegacyView), knownTypeList);
        ser.WriteObject(writer, legacyData);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多