【问题标题】:serialise bool? error reflecting type序列化布尔?错误反映类型
【发布时间】:2012-04-14 02:41:41
【问题描述】:

我有一个类似的课程

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

但是当 xml 中不存在该属性时,这会将 bool 的值序列化为 false。 当属性不在 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 有一些相关的问题,但没有任何内容显示如何使用可为空的布尔值来克服反射错误。谢谢。

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    您需要使用“*Specified”字段模式来控制它(请参阅MSDN 上的“控制生成的 XML”):

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

    现在的逻辑变成:

    • 如果!myBoolSpecified,那么myBool逻辑上是null
    • 否则使用truefalsemyBool

    【讨论】:

    • @Aliostad:我很欣赏你的方法的优点,但如果 XML 结构不开放修改,它将无法工作,而这个可以。
    • 这看起来不错,但似乎不起作用。 “{}Specified”是一个神奇的名称吗?我需要在 getter 中添加一些逻辑吗?
    • @Jules:是的,这是一个神奇的名字。在链接页面上搜索“模式是以 propertyNameSpecified 的形式创建的”。如果它不起作用,请显示您当前的代码。
    • 我对此有疑问。虽然在反序列化时确实省略了属性,但当属性具有值时,它不会将属性序列化为属性。我需要解决方案来双向工作。
    • @Jules:我不确定你的意思。序列化时属性和字段的值是多少?
    【解决方案2】:

    查看this 以获取有关处理可空字段和 XML 属性的信息。这里也有类似的question。基本上,序列化程序无法处理定义为可为空的 XML 属性字段,但有一种解决方法。

    即 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;
        }
    }
    

    【讨论】:

      【解决方案3】:

      问题是可空类型必须定义为元素(这是默认值)而不是属性。

      原因是当值为空时,它可以表示为<mybool xs:nil="true"/>,因此不能表示为属性

      看看这个sn-p:

      [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>
      

      【讨论】:

      • 谢谢,但这是我收到的 xml 中的属性,所以我无法控制。有什么办法可以让 bool 属性为空?
      【解决方案4】:

      您可以使用XmlElementAttribute.IsNullable

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

      【讨论】:

      • 只有当您可以选择序列化为元素而不是属性时,这才可行
      猜你喜欢
      • 2013-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 2021-04-20
      • 2011-12-23
      相关资源
      最近更新 更多