сериализировать бул?тип отражения ошибок - PullRequest
11 голосов
/ 30 марта 2012

У меня есть класс, подобный

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

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

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

[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.Спасибо.

Ответы [ 4 ]

10 голосов
/ 30 марта 2012

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

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

    [XmlIgnore]
    public bool myBoolSpecified;
}

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

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

Посмотрите на this для получения информации о работе с обнуляемыми полями и атрибутами XML. Здесь тоже есть похожий вопрос . По сути, сериализатор не может обработать поле атрибута XML, определенное как обнуляемое, но есть обходной путь.

I.e 2 свойства, одно из которых содержит обнуляемый (не хранится в XML), а другое используется для чтения / записи (атрибут 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;
    }
}
2 голосов
/ 18 декабря 2013

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

[Serializable]
public class MyClass
{
    [XmlElement(IsNullable = true)]
    public bool? myBool { get; set; }
}
1 голос
/ 30 марта 2012

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

Причина в том, что значение равно нулю, его можно представитькак <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>
...