Ошибки XmlSerializer после обновления с .NET 3.5 до .NET 4.6 - PullRequest
0 голосов
/ 11 февраля 2019

Итак, я недавно обновил проект с .NET 3.5 до .NET 4.6, и моя сериализация XML перестала работать.Я сузил его до одной структуры, которая, я согласен, выглядит странно.

[XmlElement("price1", typeof(PriceBonusData))]
[XmlElement("price2", typeof(PriceBonusData))]
public List<PriceBonusData> PriceBonusDataList;

Ошибка говорит о том, что мне нужно добавить атрибут XmlChoiceIdentifier в это поле, но независимо от того, как я его добавляю, онвсе еще не работает.Что кажется странным, так это то, что он работал на .NET 3.5, так почему внезапно возникла необходимость в новом атрибуте?

Правка: вот моя попытка использовать XmlChoiceIdentifier.Я видел похожие решения как в документации, так и в SO, но, похоже, у меня это не работает.

[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: я запускаю дополнительные тесты для пустого проекта с версией .NET 3.5, поэтому я решил, чтоЯ мог бы поделиться, как это ведет себя, когда это работает.

Эта структура сериализуется с использованием последнего XmlElement (в данном случае "price2").

Во время десериализации оба элемента действительны.Я вручную изменил XML-файл, чтобы он содержал «price1» и «price2», и он правильно десериализует их.

1 Ответ

0 голосов
/ 11 февраля 2019

Если вы только пытаетесь десериализовать, то, возможно, это будет работать для вас:

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

Недостатком является то, что если вы сериализуете это, все станет <price1>независимо от того, начиналось ли оно как <price1> или <price2> ... но ... я не вижу никакого способа обойти это, поскольку некуда хранить то, что было изначально.

...