2014-02-19 2 views
0

Это заметка для моего будущего «я» и для других. Описанная behavoir не очевидно ...C# XmlSerializer терпит неудачу при десериализации пустого списка перечислений, если он находится в xmlattribute

Я получил это немного C#:

public enum Choices 
{ 
    One, 
    Two, 
    Three, 
} 

public class Element 
{ 
    List<Choices> _allowedChoices; 
    [XmlAttribute] 
    public List<Choices> AllowedChoices 
    { 
    get {return _allowedChoices ?? (_allowedChoices = new List<Choices>());} 
    set { _allowedChoices = value; } 
    } 
} 

[Test] 
public void testing_empty_enum_list_serialization() 
{ 
    var ser = new XmlSerializer(typeof (Element)); 
    using (var sw = new StringWriter()) 
    { 
     ser.Serialize(sw, new Element 
     { 
      AllowedChoices = {}, 
     }); 
     var text = sw.ToString(); 
     Console.WriteLine(text); 
     using (var sr = new StringReader(text)) 
     { 
      var deserialized = (Element) ser.Deserialize(sr); 
     } 
    } 
} 

Если я использую XmlSerializer для сериализации это XML, я получаю:

(Обратите внимание, пустое AllowedChoices атрибут в конце)

<?xml version="1.0" encoding="utf-16"?> 
<Element xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" AllowedChoices="" /> 

Если я затем использовать XmlSerializer для десериализации этого XML я что-то вроде:

System.InvalidOperationException : There is an error in XML document (2, 109). 
    ----> System.InvalidOperationException : Instance validation error: '' is not a valid value for Choices. 

Это пустой лист из перечислений, сериализуемые без ошибок, Y U NO Deserialize !?

ответ

1

Я нашел эти вопросы, связанные, не прошедшие по ожидаемым причинам, а именно, что перечисление не имеет значения по умолчанию NULL, которое является ключом ...

deserializing enums

XmlSerializer enumeration deserialization failing on (non existent) whitespace

И это решение:

Если реализация AllowedChoices является авто-имуществом и не инициализируется в конструкторе (то есть это значение null, когда deserializa доходит до этого свойства), он работает так, как ожидалось, и не борется за десериализацию.

У меня есть полный контроль над источником, поэтому я буду прагматичным и добавлю значение None к моему перечислению Choices с атрибутом [XmlEnum ("")] и обрабатываю список как пустой, если это единственный значение в списке вместо не Выполнение автоматической инициализации списка.

См. http://tech.pro/blog/1370/why-collections-should-never-be-null, почему я этого хочу.

Дополнительного совет:

Если вы хотите создать пустую строку из перечисления псевдонима сделать это следующим образом:

public enum Choices 
{ 
    [XmlEnum("default")] 
    Default = 0, 

    [XmlEnum("")] 
    DefaultAlias = Default, 
} 
Смежные вопросы