XmlSerializer, xsi: тип дублируется после сериализации-десериализации-сериализации (используется атрибут XmlAnyAttribute)

#.net #xml-serialization #xmlserializer

#.net #xml-сериализация #xmlserializer

Вопрос:

У меня проблема при последовательной сериализации-десериализации-сериализации тестового класса:

 [Serializable]
public class TestClass
{
    public TestClass() { }
    public Foo Foo { get; set; }
}

[XmlInclude(typeof(Bar))]
[Serializable]
public abstract class Foo
{
    [XmlAnyAttribute]
    public List<XmlAttribute> AnyAttr;
}

[Serializable]
public class Bar : Foo
{
}

void Test()
{
  var test = new TestClass { Foo = new Bar() };
  Console.WriteLine(test.Foo.AnyAttr == null);//true

  var firstXml = Helper.SerializeToXml(test);
  Console.WriteLine(Regex.Matches(firstXml, "xsi:type=").Count);//1

  var deserialiezedObject = Helper.DeserializeFromXml<TestClass>(firstXml);
  Console.WriteLine(deserialiezedObject.Foo.AnyAttr.Count);//1
  Console.WriteLine(deserialiezedObject.Foo.AnyAttr[0].Name);//xsi:type

  var secondXml = Helper.SerializeToXml(deserialiezedObject);
  Console.WriteLine(Regex.Matches(secondXml, "xsi:type=").Count);//2

 //var secondDeserialiezedObject = Helper.DeserializeFromXml<TestClass>(secondXml); //InvalidOperationException
    }
  

полный пример

Как вы можете видеть, десериализация заполняет массив AnyAttr (на один элемент — «xsi:type»).

Странная вещь происходит после того, как мы сериализуем deserialiezedObject . Он дважды выдает «xsi: type» в теге Foo.

Является ли это ошибкой XmlSerializer или я должен каким-то образом управлять (например, удалять «xsi: type» из AnyAttr после десериализации) AnyAttr самостоятельно?

У меня есть куча автоматически сгенерированных классов, которые содержат поле AnyAttr.

Не могли бы вы подсказать, как сериализовать подобные объекты без дублирования «xsi: type»?

Ответ №1:

Попробуйте явно указать свои пространства имен для сериализатора. Я столкнулся с той же проблемой. Хотя я не был уверен, в чем причина, указание пространств имен явно, похоже, исправляет это.

Ответ №2:

Не нашел лучшего решения, чем просто удалять «xsi: type» из AnyAttr (через отражение) после каждой десериализации