【问题标题】:Trouble deserializing XML into a List<T>将 XML 反序列化为 List<T> 时遇到问题
【发布时间】:2015-01-03 12:38:58
【问题描述】:

这是我要反序列化的 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<EntityType>
  <Name>SomeName</Name>
  <Components>
    <ComponentAssembly>Some assembly name</ComponentAssembly>
  </Components>
</EntityType>

这是我用来反序列化它的数据合约:

using System.Collections.Generic;
using System.Runtime.Serialization;

namespace GameUtilities.Entities.DataContracts
{
[DataContract(Name="EntityType",Namespace="")]
public class EntityTypeData
{
    [DataMember(IsRequired=true,Order = 0)]
    public string Name { get; private set; }

    [DataMember(IsRequired=false,Order=1)]
    public List<ComponentEntry> Components { get; private set; }

    public EntityTypeData(string name, List<ComponentEntry> components = null)
    {
        Name = name;
        if(components == null)
        {
            Components = new List<ComponentEntry>();
        }
        else
        {
            Components = components;
        }
    }
}

[DataContract]
public class ComponentEntry
{
    [DataMember(IsRequired = true, Order = 0)]
    public string ComponentAssembly { get; private set; }

    public ComponentEntry(string componentAssembly)
    {
        ComponentAssembly = componentAssembly;
    }
}
}

反序列化它可以正常工作,但组件列表始终为空,无论我在标签中放置了多少条目。我尝试将组件的 [DataMemeber] 属性标记为“IsRequired=true”,并且反序列化仍然完成且没有错误,但未填充列表。你能看出我的数据合同有什么问题会导致这个失败吗?

编辑:作为测试,我使用上面的数据协定通过序列化程序运行了一个对象,以查看 XML 吐出的内容。这是我看到的:

<EntityType xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Name>TESTNAME</Name>
    <Components xmlns:a="http://schemas.datacontract.org/2004/07/GameUtilities.Entities.DataContracts">
        <a:ComponentEntry>
            <a:ComponentAssembly>ONE</a:ComponentAssembly>
        </a:ComponentEntry>
        <a:ComponentEntry>
            <a:ComponentAssembly>TWO</a:ComponentAssembly>
        </a:ComponentEntry>
        <a:ComponentEntry>
            <a:ComponentAssembly>THREE</a:ComponentAssembly>
        </a:ComponentEntry>
   </Components>

这是我使用的序列化代码:

public static void SerializeObject<T>(string path, T obj)
    {
        FileStream fs = new FileStream(path,FileMode.Create);
        XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs);
        DataContractSerializer ser = new DataContractSerializer(typeof(T));

        //Serialize the data to a file
        ser.WriteObject(writer, obj);
        writer.Close();
        fs.Close();
    }

如您所见,为列出的每个 ComponentAssembly 创建了一个单独的 ComponentEntry。有没有办法摆脱它而只获得 ComponentAssembly?

【问题讨论】:

  • 公开你的组件设置器
  • 请发布您的序列化代码

标签: c# xml serialization collections


【解决方案1】:

最简单的解决方案是定义一个收集数据合同。在使用DataContractSerializer 时,我认为没有办法将ComponentEntry 作为单独的类型。

[DataContract(Name="EntityType",Namespace="")]
public class EntityTypeData
{
    [DataMember(IsRequired=true,Order=0)]
    public string Name { get; private set; }

    [DataMember(IsRequired=false,Order=1)]
    public ComponentList Components { get; private set; }

    public EntityTypeData(string name, IEnumerable<string> components = null)
    {
        Name = name;
        Components = new ComponentList();
        if(components != null)
        {
            Components.AddRange(components);
        }
    }
}

[CollectionDataContract(ItemName = "ComponentAssembly", Namespace="")]
public class ComponentList : List<string> {}
var ser = new DataContractSerializer(typeof(EntityTypeData));
var entity = (EntityTypeData) ser.ReadObject(stream);

【讨论】:

    猜你喜欢
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多