Serialise bool? отражающий тип ошибки

У меня есть класс вроде

   [Serializable]
    public class MyClass
    {
        [XmlAttribute]
        public bool myBool { get; set; }
    }

Но это сериализует значение bool на false, если атрибут отсутствует в xml. Когда атрибут отсутствует в xml, я хочу, чтобы свойство было null.

Итак, я попробовал это

[Serializable]
public class MyClass
{
    [XmlAttribute]
    public bool? myBool { get; set; }
}

Но тогда ошибки сериализатора

Type t = Type.GetType("Assembly.NameSpace.MyClass");
                XmlSerializer mySerializer = new XmlSerializer(t); //error "There was an error reflecting type"

Пожалуйста, дайте мне пример того, как я могу это сделать. Я знаю, что есть некоторые связанные вопросы о SO, но ничего, что показывает, как преодолеть ошибку отражения с помощью nullable bool. Спасибо.

Ответ 1

Для управления этим полем необходимо использовать "* Указанный" шаблон поля (см. "Управление генерируемым XML" на MSDN):

[Serializable]
public class MyClass
{
    [XmlAttribute]
    public bool myBool { get; set; }

    [XmlIgnore]
    public bool myBoolSpecified;
}

Теперь логика становится:

  • Если !myBoolSpecified, то myBool логически null
  • В противном случае используйте true или false в myBool

Ответ 2

Посмотрите этот для получения информации о работе с полями с возможностью NULL и атрибутами XML. Здесь также есть question. В принципе, сериализатор не может обрабатывать поле атрибута XML, определяемое как NULL, но существует обход.

I.e 2 свойства, которые содержат нулевую (не сохраненную XML), а другую, которая используется в read/writing (атрибут XML, хранящийся в виде строки). Возможно, это может быть то, что вам нужно?

private bool? _myBool;
[XmlIgnore]
public bool? MyBool
{
    get
    {
        return _myBool;
    }
    set
    {
        _myBool = value;
    }
}

[XmlAttribute("MyBool")]
public string MyBoolstring
{
    get
    {
        return MyBool.HasValue
        ? XmlConvert.ToString(MyBool.Value)
        : string.Empty;
    }
    set
    {
        MyBool =
        !string.IsNullOrEmpty(value)
        ? XmlConvert.ToBoolean(value)
        : (bool?)null;
    }
}

Ответ 3

Вы можете использовать XmlElementAttribute.IsNullable:

[Serializable]
public class MyClass
{
    [XmlElement(IsNullable = true)]
    public bool? myBool { get; set; }
}

Ответ 4

Проблема заключается в том, что тип с нулевым значением должен быть определен как элемент (по умолчанию), а не атрибут.

Причина в том, что значение равно null, оно может быть представлено как <mybool xs:nil="true"/>, так как не может быть представлено как атрибут.

Взгляните на этот фрагмент:

[Serializable]
public class MyClass
{
    // removed the attribute!!!
    public bool? myBool { get; set; }
}

и

XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
var stream = new MemoryStream();
serializer.Serialize(stream, new MyClass(){myBool = null});
Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray()));

Вывод:

<?xml version="1.0"?>
<MyClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.o
rg/2001/XMLSchema-instance">
  <myBool xsi:nil="true" /> <!-- NOTE HERE !!! -->
</MyClass>