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