xmlns ='' не ожидался, когда десериализация вложила классы

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

На сервере у меня есть следующие два класса:

[XmlRoot("StatusUpdate")]
public class GameStatusUpdate
{
    public GameStatusUpdate()
    {}

    public GameStatusUpdate(Player[] players, Command command)
    {
        this.Players = players;
        this.Update = command;
    }

    [XmlArray("Players")]
    public Player[] Players { get; set; }

    [XmlElement("Command")]
    public Command Update { get; set; }
}

и

[XmlRoot("Player")]
public class Player
{
    public Player()
    {}

    public Player(PlayerColors color)
    {
        Color = color;
        ...
    }

    [XmlAttribute("Color")]
    public PlayerColors Color { get; set; }

    [XmlAttribute("X")]
    public int X { get; set; }

    [XmlAttribute("Y")]
    public int Y { get; set; }
}

(Недостающие типы являются всеми перечислениями).

Это генерирует следующий XML на сериализации:

<?xml version="1.0" encoding="utf-16"?>
<StatusUpdate>
  <Players>
    <Player Color="Cyan" X="67" Y="32" />
  </Players>
  <Command>StartGame</Command>
</StatusUpdate>

На стороне клиента я пытаюсь десериализовать это в следующие классы:

[XmlRoot("StatusUpdate")]
public class StatusUpdate
{
    public StatusUpdate()
    {

    }

    [XmlArray("Players")]
    [XmlArrayItem("Player")]
    public PlayerInfo[] Players { get; set; }

    [XmlElement("Command")]
    public Command Update { get; set; }
}

и

[XmlRoot("Player")]
public class PlayerInfo
{
    public PlayerInfo()
    {
    }

    [XmlAttribute("X")]
    public int X { get; set; }

    [XmlAttribute("Y")]
    public int Y { get; set; }

    [XmlAttribute("Color")]
    public PlayerColor Color { get; set; }
}

Однако deserializer выдает исключение:

There is an error in XML document (2, 2).
<StatusUpdate xmlns=''> was not expected.

Что я пропускаю или делаю неправильно?

Править:

По запросу я также добавляю, что код раньше сериализировал и десериализовывал:

Сервер:

    public static byte[] SerializeObject(Object obj)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
        StringWriter writer = new StringWriter();

        // Clear pre-defined namespaces
        XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
        xsn.Add("", "");

        xmlSerializer.Serialize(writer, obj, xsn);
        writer.Flush();

        // Send as little-endian UTF-16 string because the Serializer denotes XML as 
        // utf-18 which cannot be easly changed
        UnicodeEncoding encoder = new UnicodeEncoding(false, false);
        return encoder.GetBytes(writer.ToString());
    }

Клиент:

    public static object DeserializeXml(string xmlData, Type type)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(type);


        StringReader reader = new StringReader(xmlData);
        object obj = xmlSerializer.Deserialize(reader);

        return obj;
    }

Десериализация вызывается с

StatusUpdate update = (StatusUpdate) Util.DeserializeXml(xmlData, typeof (StatusUpdate));
8
задан Mavrik 9 May 2010 в 14:05
поделиться

2 ответа

После долгих тестов я наконец нашел ошибку. Это была не проблема кодировки, не проблема в другом коде и не проблема отсутствующего пространства имен.

Недостающей частью была аннотация для типа объектов в массиве при десериализации.

Поэтому мне пришлось изменить класс StatusUpdate на

[XmlRoot("StatusUpdate")]
public class StatusUpdate
{
    public StatusUpdate()
    {

    }

    [XmlArray("Players"), XmlArrayItem(ElementName = "Player", Type = typeof(PlayerInfo))]
    public PlayerInfo[] Players { get; set; }

    [XmlElement("Command")]
    public ServerCommand Update { get; set; }
}

и сериализация стала работать отлично.

Надеюсь, это поможет кому-нибудь еще.

18
ответ дан 5 December 2019 в 07:10
поделиться

На самом деле это очень необычно при использовании XmlSerializer . Корневой элемент всегда должен выглядеть следующим образом:

<MyClass 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

(Исправление: XmlSerializer , похоже, работает без них при десериализации, но он всегда добавляет их при сериализации, так что что-то подозрительно, если они отсутствует.)

Вторая правка:

Я сильно подозреваю, что ваша проблема связана с кодировкой. Я не знаю, почему вы так сильно возитесь с сериализацией и не можете просто использовать кодировку UTF-8 по умолчанию, но, тем не менее, следующий код работает без каких-либо ошибок:

MyClass m = new MyClass() { X = 4, Y = 8 };
byte[] data = SerializeObject(m);
string xml = Encoding.Unicode.GetString(data);
Console.WriteLine(xml);
m = (MyClass)DeserializeXml(xml, typeof(MyClass));

Итак, если у вас что-то не получается, очень вероятно, что при преобразовании массива байтов в строку XML на стороне клиента происходит сбой. Это единственный код, который вы еще не опубликовали .

2
ответ дан 5 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: