CollectionDataContract序列化不添加自定义属性(DataMember)

时间:2011-09-21 14:27:36

标签: c# serialization datacontractserializer datacontract datamember

我们有一个遗留系统需要以非结构化格式提供(XML)数据。使用.NET DataContractSerializer可以实现以下功能吗?

给出以下DataContracts

[CollectionDataContract(Name = "Options", ItemName = "Option")]
public class OptionItemCollection : List<OptionItem>
{
    [DataMember(Name = "Name")]
    public string Name { get; set; }

    public OptionItemCollection()
    {
    }

    public OptionItemCollection(IEnumerable<OptionItem> items) : base(items)
    {
    }
}

[DataContract(Name = "Option")]
public class OptionItem
{
    [DataMember]
    public string Text { get; set; }
    [DataMember]
    public string Value { get; set; }

}

是否可以将此集合直接序列化为以下XML表示形式:

<Options>
    <Name>Juices</Name>
    <Option Value="1">Orange Juice</Option>
    <Option Value="2">Pineapple</Option>
    <Option Value="3">Fruit Punch</Option>
</Options>

注意: 这正是遗留系统期望提交数据的方式。

甚至:

<Options>
    <Name>Juices</Name>
    <Option><Value>1</Value><Text>Orange Juice</Text></Option>
    <Option><Value>2</Value><Text>Pineapple</Text></Option>
    <Option><Value>3</Value><Text>Fruit Punch</Text></Option>
</Options>

另请注意,重点在于选项元素中的名称选项元素。< / p>

2 个答案:

答案 0 :(得分:4)

是。虽然DataContractSerializer没有明确支持XML属性,但您可以手动滚动它。试试这个:

[CollectionDataContract(Name = "Options", ItemName = "Option")]
public class OptionItemCollection : List<OptionItem>
{
    [DataMember(Name = "Name")]
    public string Name { get; set; }

    public OptionItemCollection()
    {
    }

    public OptionItemCollection(IEnumerable<OptionItem> items)
        : base(items)
    {
    }
}

// note, remove attributes
public class OptionItem : IXmlSerializable
{
    public string Text { get; set; }

    public string Value { get; set; }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString("Value", Value);
        writer.WriteElementString("Text", Text);
    }

    public void ReadXml(XmlReader reader)
    {
        // implement if necessary
        throw new NotImplementedException();
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:4)

不,DataContractSerializer(DCS)无法做到这一点。 DCS不允许展开的收集元素。所以你不能拥有这个:

<a>
  <b/>
  <b/>
  <b/>
  <c/>
</a>

但你可以这样:

<a>
  <bb>
    <b/>
    <b/>
    <b/>
  </bb>
  <c/>
</a>

在您的方案中,您需要使用XmlSerializer