C#object< - >数据合同序列化/反序列化会添加一些不需要的标记

时间:2011-10-29 04:28:37

标签: c# xml serialization datacontractserializer

我正面临着一种烦人的情况,即我的序列化/反序列化并不像预期的那样。

我想要

<OuterClass>
  <Assets>
      <Asset>Asset_A</Asset>
      <Asset>Asset_B</Asset>
  </Assets>
  ...
</OuterClass> 

但我正在

<OuterClass>
  <Assets>
    <Asset>
      <Asset>Asset_A</Asset>
    </Asset>
    <Asset>
      <Asset>Asset_B</Asset>
    </Asset>
  </Assets>
  ...
</OuterClass>

正如您所见,资产标记出现两次。

执行此操作的代码是..

public class OuterClass
{
    [DataMember(Name = "Assets", Order = 10)]
    public List<AssetClass> Assets { get; set; }
    ...
    [DataContract(Name = "Asset", Namespace = "")]
    public class AssetClass
    {
        [DataMember(Name = "Asset", Order = 10)]
        public string Asset { get; set; }
        ...
    } 
}

我知道我在代码中也列出了两次'Name =“Asset”',但是如果我取出其中任何一个,那么框架会在里面添加它自己的名字。不知怎的,我怀疑我需要改变代码本身的结构,但不知道如何做到这一点。

(编辑) 我正在使用框架内序列化/反序列化帮助程序。代码是(简化):

public string ToXmlString(OuterClass AssetsWrapper)
{
    DataContractSerializer ser = new DataContractSerializer(typeof(OuterClass));            
    MemoryStream memStream = new MemoryStream();

    // Convert object -> stream -> byte[] -> string (whew!)
    ser.WriteObject(memStream, AssetsWrapper);
    byte[] AssetsWrapperByte = memStream.ToArray();
    return Encoding.UTF8.GetString(AssetsWrapperByte);
}

4 个答案:

答案 0 :(得分:1)

所以你看到的是OuterClass,然后它与你的AssetClass列表相对应 然后每个,最后每个AssetClass.Asset属性被序列化为另一个标记。

如果没有自己实现序列化(通过ISerialize,我相信),你无法获得所需的XML输出。

答案 1 :(得分:1)

您需要将List<AssetClass> Assets { get; set; }更改为List<string> Assets { get; set; },并为子元素名称添加XmlElement属性,并对您的班级进行一些更改:

public class OuterClass
{
    [DataMember(Name = "Assets", Order = 10),
    XmlElement(ElementName = "Asset")]
    public List<string> Assets { get; set; }
    ...
    //[DataContract(Name = "Asset", Namespace = "")]
    //public class AssetClass
    //{
    //  [DataMember(Name = "Asset", Order = 10)]
    //  public string Asset { get; set; }
    //  ...
    //} 
}

希望这有帮助!

答案 2 :(得分:1)

您可以使用XmlSerializer代替DataContractSerializer,这样可以更好地控制XML

答案 3 :(得分:0)

好的,所以我能够通过修改两个类标记以及实际的序列化/反序列化代码来解决这个.NET序列化的怪异问题。尽管答案并没有按原样发挥作用,但多亏了托马斯和穆尼姆的暗示,这些暗示使我在经过一些实验后走上了正确的道路。

序列化更改

用XmlSerializer替换DataContractSerializer。这完全糟糕,因为它慢了很多(500%):( ... performance here

public string ToXmlString(OuterClass AssetsWrapper)
{
    XmlSerializer ser = new XmlSerializer(typeof(OuterClass));            
    MemoryStream memStream = new MemoryStream();

    // Convert object -> stream -> byte[] -> string (whew!)
    ser.WriteObject(memStream, AssetsWrapper);
    byte[] AssetsWrapperByte = memStream.ToArray();
    return Encoding.UTF8.GetString(AssetsWrapperByte);
}

类标记更改

public class OuterClass
{
    [DataMember(Name = "Assets", Order = 10)]
    public ListAssetClass Assets { get; set; }
    ...

    //[DataContract(Name = "Asset123", Namespace = "")]
    public class ListAssetClass
    {
        [XmlElement(ElementName = "Asset")]
        public List<string> Assets { get; set; }
        ...
    }
}

现在给了我

<Assets>
  <Asset>Asset One</Asset>
  <Asset>Asset Two</Asset>
</Assets>

我很惊讶框架序列化/反序列化是如此扭曲和缓慢。我可能不得不在某个时候寻找外部库。