Reputation: 134
So I recently updated a project from .NET 3.5 to .NET 4.6 and my XML serialization stopped working. I narrowed it down to a single structure that, I agree, looks weird.
[XmlElement("price1", typeof(PriceBonusData))]
[XmlElement("price2", typeof(PriceBonusData))]
public List<PriceBonusData> PriceBonusDataList;
The error says that I need to add XmlChoiceIdentifier
attribute to this field, but no matter how I add it, it still doesn't work. What seems strange is that it did work on .NET 3.5, so why the sudden need for new attribute?
Edit: here is my attempt to use XmlChoiceIdentifier. I saw similar solutions both in documentation and on SO, but it doesn't seem to work for me.
[XmlElement(IsNullable = false)]
[XmlIgnore]
public ItemChoiceType[] ItemTypeArray = (ItemChoiceType[])Enum.GetValues(typeof(ItemChoiceType));
[XmlChoiceIdentifier("ItemTypeArray")]
[XmlElement("price1", typeof(PriceBonusData))]
[XmlElement("price2", typeof(PriceBonusData))]
public List<PriceBonusData> PriceBonusDataList;
[XmlType(IncludeInSchema = false)]
public enum ItemChoiceType
{
[XmlEnum("price1")]
price1,
[XmlEnum("price2")]
price2
}
Edit2: I run some further tests on an empty project with .NET 3.5 version so I figured I could share how this behaves when this works.
This structure is serialized using last XmlElement (in this case "price2").
During deserialization both elements are valid. I manually changed XML file so it contains both "price1" and "price2" and it deserializes them correctly.
Upvotes: 2
Views: 240
Reputation: 1063774
If you're only trying to deserialize, then maybe this will work for you:
public class Foo
{
// the "real" list that takes <price1> elements
[XmlElement("price1", typeof(PriceBonusData))]
public List<PriceBonusData> PriceBonusDataList {get;} = new List<PriceBonusData>();
// spoof a second list that handles <price2> elements (actually: the same list)
[XmlElement("price2", typeof(PriceBonusData))]
public List<PriceBonusData> PriceBonusDataList2 => PriceBonusDataList;
// this disables serialization of PriceBonusDataList2 so we don't double up
public bool ShouldSerializePriceBonusDataList2() => false;
}
The downside is that if you serialize it, everything will become <price1>
, regardless of whether it started as a <price1>
or <price2>
... but... I can't see any way around that, since there's nowhere to store what it was originally.
Upvotes: 1