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; }
}
однако десериализатор выдает исключение:
There is an error in XML document (2, 2).
<StatusUpdate xmlns=''> was not expected.
что я упускаю или делаю не так?
EDIT:
по запросу я также добавляю код, используемый для сериализации и десериализации:
сервер:
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));
4 ответов
после большого количества тестов я, наконец, нашел ошибку. Это не была проблема кодирования, ни проблема в другом коде, ни отсутствующее пространство имен.
отсутствующая часть была аннотацией для типа объектов в массиве при десериализации.
поэтому мне пришлось изменить свой 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; }
}
и сериализация начала работать отлично.
Я надеюсь, что это поможет кому-то еще.
вот что решило это для меня:
[System.Xml.Serialization.XmlRootAttribute("nodeName", Namespace = "http://somenamespace", IsNullable = false)]
это на самом деле очень необычно видеть при использовании 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 на стороне клиента. Это единственный код, который вы все еще не выложил.
Я решил со следующим
XmlSerializer serializer = new XmlSerializer(typeof(CustomerPhoto), "http://example.com/webservices/");
CustomerPhoto returnObject = (CustomerPhoto)serializer.Deserialize(xmlStream);