我有一个可以为空的int类?数据类型设置为序列化为xml元素.有没有办法设置它,所以如果值为null,xml序列化程序将不会序列化该元素?
我试图添加[System.Xml.Serialization.XmlElement(IsNullable = false)]属性,但我得到一个运行时序列化异常,说有一个反映类型的错误,因为"IsNullable可能不会设置为'false '对于Nullable类型.考虑使用'System.Int32'类型或从XmlElement属性中删除IsNullable属性."
[Serializable] [System.Xml.Serialization.XmlRoot("Score", Namespace = "http://mycomp.com/test/score/v1")] public class Score { private int? iID_m; ... ////// /// public int? ID { get { return iID_m; } set { iID_m = value; } } ... }
上面的类将序列化为:
但对于null的ID,我根本不需要ID元素,主要是因为当我在MSSQL中使用OPENXML时,对于看起来像的元素,它返回0而不是null
XmlSerializer支持该ShouldSerialize{Foo}()
模式,因此您可以添加一个方法:
public bool ShouldSerializeID() {return ID.HasValue;}
还有{Foo}Specified
模式 - 不确定XmlSerializer是否支持那个模式.
我正在使用这个微模式来实现Nullable序列化:
[XmlIgnore] public double? SomeValue { get; set; } [XmlAttribute("SomeValue")] // or [XmlElement("SomeValue")] [EditorBrowsable(EditorBrowsableState.Never)] public double XmlSomeValue { get { return SomeValue.Value; } set { SomeValue= value; } } [EditorBrowsable(EditorBrowsableState.Never)] public bool XmlSomeValueSpecified { get { return SomeValue.HasValue; } }
这为用户提供了正确的界面而且没有任何妥协,在序列化时仍然做正确的事情.
我想出了一个使用两个属性的解决方法.一个int?具有XmlIgnore属性的属性和要序列化的对象属性.
////// Score db record /// [System.Xml.Serialization.XmlIgnore()] public int? ID { get { return iID_m; } set { iID_m = value; } } ////// Score db record /// [System.Xml.Serialization.XmlElement("ID",IsNullable = false)] public object IDValue { get { return ID; } set { if (value == null) { ID = null; } else if (value is int || value is int?) { ID = (int)value; } else { ID = int.Parse(value.ToString()); } } }
哇谢谢这个问题/答案真的帮助了我.我心脏Stackoverflow.
我把你正在做的事情做得更加通用了.我们真正想要的是让Nullable具有略微不同的序列化行为.我使用Reflector来构建我自己的Nullable,并在这里和那里添加了一些东西,使XML序列化按照我们想要的方式工作.似乎工作得很好:
public class Nullable{ public Nullable(T value) { _value = value; _hasValue = true; } public Nullable() { _hasValue = false; } [XmlText] public T Value { get { if (!HasValue) throw new InvalidOperationException(); return _value; } set { _value = value; _hasValue = true; } } [XmlIgnore] public bool HasValue { get { return _hasValue; } } public T GetValueOrDefault() { return _value; } public T GetValueOrDefault(T i_defaultValue) { return HasValue ? _value : i_defaultValue; } public static explicit operator T(Nullable i_value) { return i_value.Value; } public static implicit operator Nullable (T i_value) { return new Nullable (i_value); } public override bool Equals(object i_other) { if (!HasValue) return (i_other == null); if (i_other == null) return false; return _value.Equals(i_other); } public override int GetHashCode() { if (!HasValue) return 0; return _value.GetHashCode(); } public override string ToString() { if (!HasValue) return ""; return _value.ToString(); } bool _hasValue; T _value; }
你失去了将你的成员作为int的能力?等等(必须使用Nullable