CollectionDataContract serialization not adding custom properties (DataMember)

冷暖自知 提交于 2021-01-29 02:54:31

问题


We have a legacy system that needs to be fed (XML) data in a most unstructured format. Is the following even possible with the .NET DataContractSerializer?

Given the following 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; }

}

Is it possible to serialize this collection directly into the following XML representation:

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

NOTE: This is exactly how the legacy system expects the data to be submitted.

Or Even:

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

Also NOTE that the emphasis is on the Name and Option element residing within the Options element.


回答1:


Yes. Although the DataContractSerializer doesn't explicitly support XML attributes, you can hand-roll it. Try this:

[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();
    }
}



回答2:


No, this is not possible with the DataContractSerializer (DCS). The DCS doesn't allow unwrapped collection elements. So you cannot have this:

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

But you can have this:

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

In your scenario you'll need to use the XmlSerializer.



来源:https://stackoverflow.com/questions/7501526/collectiondatacontract-serialization-not-adding-custom-properties-datamember

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!