Ошибки XmlSerializer после обновления с .NET 3.5 до .NET 4.6

2

Поэтому я недавно обновил проект с .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", и он правильно десериализует их.

Показать ещё 2 комментария
Теги:
serialization
xml-serialization

1 ответ

1

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

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>... но... я не вижу никакого способа обойти это, так как нет нигде хранить то, что было изначально.

  • 0
    Основная проблема любого решения, требующего написания отдельных коллекций для разных элементов, заключается в том, что я сократил этот пример. В коде этот список имеет 37 тегов XmlElement. Также мне бы очень хотелось узнать, почему он работал в предыдущей версии .NET
  • 0
    @WojtekPojda ой ... хорошо, позвольте мне взглянуть на альтернативы в секунду ... (но: это работает!)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню