Конструкция XmlSerializer с одноименными дополнительными типами - PullRequest
0 голосов
/ 19 декабря 2009

Эй, у меня проблемы с созданием XmlSerializer, где дополнительные типы содержат типы с одинаковыми именами (но уникальными полными именами). Ниже приведен пример, иллюстрирующий мой сценарий.

Определения типов во внешней сборке, которыми я не могу манипулировать:

public static class Wheel
{
  public enum Status { Stopped, Spinning }
}

public static class Engine
{
  public enum Status { Idle, Full }
}

Класс, который я написал и который контролирует:

public class Car
{
  public Wheel.Status WheelStatus;
  public Engine.Status EngineStatus;

  public static string Serialize(Car car)
  {
    var xs = new XmlSerializer(typeof(Car), new[] {typeof(Wheel.Status),typeof(Engine.Status)});

    var output = new StringBuilder();
    using (var sw = new StringWriter(output))
      xs.Serialize(sw, car);

    return output.ToString();
  }
}

Конструктор XmlSerializer создает исключение System.InvalidOperationException с сообщением

«Произошла ошибка при отображении типа« Engine.Status »»

Это исключение имеет исключение InnerException типа System.InvalidOperationException и с сообщением

«Типы« Wheel.Status »и« Engine.Status »используют имя типа XML« Status »из пространства имен«. Используйте атрибуты XML для указания уникального имени XML и / или пространства имен для типа ».

Учитывая, что я не могу изменить типы перечисления, как я могу создать XmlSerializer, который будет успешно сериализовать Car?

Ответы [ 4 ]

0 голосов
/ 02 октября 2018

Вы можете просто добавить [XmlElement(Name = "WheelStatus")] прямо над вашей переменной "Status", чтобы избежать этой проблемы.

Это принудительно переименовывает имя xml при сохранении (и ожидаемое имя при загрузке) в любую строку, указанную в «Имя». Но это также позволит вам сохранить имя переменной "status"

0 голосов
/ 19 декабря 2009

вы можете сериализовать его, реализовав интерфейс IXmlSerializable для каждого из классов, тогда вы получите 3 метода

GetSchema()
ReadXml()
WriteXml()

в методе GetSchema просто укажите return null;, а в методе WriteXml () укажите код, необходимый для написания xml, при сериализации объекта, а в методе ReadXml () - код, необходимый для чтения файла xml и создания заново объект при десериализации.

0 голосов
/ 21 декабря 2009

Попробуйте использовать атрибут XmlElement:

public class Car
{
    [XmlElement("WheelStatus")]
    public Wheel.Status WheelStatus;
    [XmlElement("EngineStatus")]
    public Engine.Status EngineStatus;

    ...

}

ОБНОВЛЕНИЕ: только что попробовал это, и это, кажется, не работает в этом случае.

0 голосов
/ 19 декабря 2009

Первое, что я заметил, это то, что Car.Status не существует. Вы имеете в виду Engine.Status?

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

...