powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / XmlSerializer+base class+XmlTextAttribute - InvalidOperationException
3 сообщений из 3, страница 1 из 1
XmlSerializer+base class+XmlTextAttribute - InvalidOperationException
    #40058055
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дано (в сжатом виде):
1. Примерно такая схема:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="item">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:int">
                <xs:attribute name="name" type="xs:string" use="required" />
                <xs:attribute name="type" type="xs:string" use="required" />
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>


В реальной рабочей схеме имеется куча объявленных xs:complexType c одинаковым набором атрибутов, эти типы отличаются только базой контента.
2. На основании схемы генерим с пом. xsd.exe класс, слегка дорабатываем напильником:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
[System.Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(ElementName = "root", Namespace = "", IsNullable = false)]
public class Root
{
  [XmlElement("item")]
  public RootItem Item { get; set; }
}

[System.Serializable]
[XmlType(AnonymousType = true)]
public class RootItem
{
  [XmlAttribute("name")]
  public string Name { get; set; }
  [XmlAttribute("type")]
  public string Type { get; set; }
  [XmlText]
  public int Value { get; set; }
}


пробуем делать десериализацию:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
try
{
  using (var sr = new StringReader("<root><item name='foo' type='bar'>123</item></root>"))
  {
    if (!(new XmlSerializer(typeof(Root)).Deserialize(sr) is Root r))
      throw new InvalidOperationException("Not instace of Root");
    Console.WriteLine(r);
  }
}
catch(Exception e)
{
  Console.WriteLine(e);
}


- всё ок. Теперь, поскольку см. выше про кучу типов с одинаковым набором атрибутов, меняем класс RootItem так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public class RootItemBase
{
  [XmlAttribute("name")]
  public string Name { get; set; }
  [XmlAttribute("type")]
  public string Type { get; set; }
}

[System.Serializable]
[XmlType(AnonymousType = true)]
public class RootItem : RootItemBase
{
  [XmlText]
  public int Value { get; set; }
}


и при десериализации ловим:

Код: plaintext
1.
2.
3.
4.
System.InvalidOperationException: There was an error reflecting type 'test2.Root'.
  ---> System.InvalidOperationException: There was an error reflecting property 'Item'.
  ---> System.InvalidOperationException: There was an error reflecting type 'test2.RootItem'.
  ---> System.InvalidOperationException: Cannot serialize object of type 'test2.RootItem'.
 Consider changing type of XmlText member 'test2.RootItem.Value' from System.Int32 to string or string array. 

Я, конечно, могу это свойство сделать стринговым, и дополнительно завести вычисляемое на основе Value числовое свойство с XmlIgnore - но какого? Почему наличие базового класса ломает сериализацию XmlText? Что не так?
И да, методом научного тыка выяснилось, что для воспроизведения ошибки достаточно, чтобы сериализумый класс просто наследовался от чего-нибудь, отличного от object - т.е. аналогичная ошибка будет и вот в такоим случае:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public class RootItemBase
{
}

[System.Serializable]
[XmlType(AnonymousType = true)]
public class RootItem : RootItemBase
{
  [XmlAttribute("name")]
  public string Name { get; set; }
  [XmlAttribute("type")]
  public string Type { get; set; }
  [XmlText]
  public int Value { get; set; }
}


Это вообще можно как-нибудь побороть?
...
Рейтинг: 0 / 0
XmlSerializer+base class+XmlTextAttribute - InvalidOperationException
    #40058155
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
XmlSerializer+base class+XmlTextAttribute - InvalidOperationException
    #40058193
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ

Спасибо, но увы, не помогло.
Выяснилось, что это достаточно известный баг - известный в т.ч. разработчикам дотнета. Ответ от них тоже стандартный: да, знаем, раз пути обхода (в виде decorated properties) есть, то исправлять не будем, а то очень дофига придётся исправлять: https://github.com/dotnet/runtime/issues/22656
Значит, придётся использовать эти decorated properties.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / XmlSerializer+base class+XmlTextAttribute - InvalidOperationException
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]