【问题标题】:xml serialization error on bool typesbool类型的xml序列化错误
【发布时间】:2012-05-17 17:12:46
【问题描述】:

我正在尝试找出如何解决从驼峰字符串中序列化布尔类型的问题。

我有以下xml

<Root>
  <BoolElement>
     False
  </BoolElement>
</Root>

和下面的类

[XmlRoot("Root")]
public class RootObj{
  [XmlElement("BoolElement")]
  public bool BoolElement{get;set;}
}

这会产生错误。

如果我使用相同的类并将“False”重命名为“false”,它将起作用。问题是我无法编辑 xml。

有谁知道我该如何解决这个问题?

【问题讨论】:

  • 这不是反序列化而不是序列化吗?

标签: asp.net xml-serialization


【解决方案1】:

您可以使用支持字段来帮助反序列化此无效 XML(我说无效是因为根据 xsd:boolean 架构 False 是无效值):

[XmlRoot("Root")]
public class RootObj
{
    [XmlElement("BoolElement")]
    public string BackingBoolElement
    {
        set
        {
            BoolElement = bool.Parse(value.ToLower());
        }
        get
        {
            return BoolElement.ToString();
        }
    }

    [XmlIgnore]
    public bool BoolElement { get; set; }
}

【讨论】:

  • 我认为默认的 Xml 序列化没有注意到既不读写又不公开的属性?
  • @DarinDimitrov 我尝试了类似的方法,但我错过了使用 XmlIgnore :非常感谢!
  • 最后,这不是一个解决方案,因为它只返回 false。我用 true 尝试过,它坚持返回 false
  • @StrouMfios,你是对的。 XmlSerializer 期望该属性具有公共 getter 和 setter。我已经更新了我的答案。
  • 我用与你类似的方式编辑它 [XmlElement("BoolElement")] public string BackingBoolElement{ get;放; } [XmlIgnore] public bool BoolElement { get { return bool.Parse(BackingBoolElement); } } 再次感谢
【解决方案2】:

False 不是 valid value for an xsd:boolean(但正如您所注意到的,false0 是) - 如果您无法更改源数据,那么您可以拥有一个单独的属性,纯粹用于 XML 序列化:

[XmlRoot("Root")]
public class RootObj{
  [XmlElement("BoolElement")]
  public string BoolElementForSerialization
  {
     get
     {
         return (this.BoolElement ? "True" : "False");
     }
     set
     {
         this.BoolElement = (string.Compare(value, "false", StringComparison.OrdinalIgnoreCase) != 0);
     }
  }

  [XmlIgnore]
  public bool BoolElement{get;set;}
}

【讨论】:

    【解决方案3】:

    我创建了一个可以从任何字符串反序列化的新布尔类型。它可能并不完美,但它适合我当时的需求。

    对于您要使用的类,只需将数据类型从 bool 更改为 SerializableBoolean:

    [XmlRoot("Root")]
    public class RootObj{
      [XmlElement("BoolElement")]
      public SerializableBoolean BoolElement{get;set;}
    }
    

    然后您可以像使用任何普通 bool 数据类型一样使用 BoolElement 属性:

    RootObj myObj = new RootObj();
    if (myObj.BoolElement) { ... }
    

    这是 SerializableBoolean 类的代码,请注意,此代码仅处理反序列化,序列化为 xml 不是我的目的所必需的,因此未实现。

    [System.Diagnostics.DebuggerDisplay("{Value}")]
    public struct SerializableBoolean: System.Xml.Serialization.IXmlSerializable
    {
        private bool Value { get; set; }
    
        public override bool Equals(object obj)
        {
            if (obj is string stringBoolean)
            {
                bool.TryParse(stringBoolean, out bool boolean);
                return Value == boolean;
            }
            else if (obj is bool boolean)
            {
                return Value == boolean;
            }
            else if (obj is SerializableBoolean serializableBoolean)
            {
                return Value == serializableBoolean.Value;
            }
            else
            {
                return Value == Convert.ToBoolean(obj);
            }
        }
    
        public override int GetHashCode()
        {
            return -1937169414 + Value.GetHashCode();
        }
    
        public XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }
    
        public void ReadXml(XmlReader reader)
        {
            Value = Convert.ToBoolean(reader.ReadElementContentAsString());
        }
    
        public void WriteXml(XmlWriter writer)
        {
            throw new NotImplementedException();
        }
    
        public static bool operator ==(SerializableBoolean obj1, bool obj2)
        {
            return obj1.Value.Equals(obj2);
        }
        public static bool operator !=(SerializableBoolean obj1, bool obj2)
        {
            return !obj1.Value.Equals(obj2);
        }
    
        public static implicit operator SerializableBoolean(string value)
        {
            return new SerializableBoolean() { Value = Convert.ToBoolean(value) };
        }
    
        public static implicit operator SerializableBoolean(bool value)
        {
            return new SerializableBoolean() { Value = value };
        }
    
        public static implicit operator bool(SerializableBoolean b)
        {
            return b.Value;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多