Saya memiliki kelas dengan int nullable? datatype diatur ke serial sebagai elemen xml. Apakah ada cara untuk mengaturnya sehingga xml serializer tidak akan membuat serial elemen jika nilainya null?
Saya telah mencoba menambahkan atribut [System.Xml.Serialization.XmlElement (IsNullable = false)], tetapi saya mendapatkan pengecualian serialisasi runtime yang mengatakan ada kesalahan yang mencerminkan jenisnya, karena "IsNullable mungkin tidak disetel ke 'salah 'untuk tipe Nullable. Pertimbangkan untuk menggunakan tipe' System.Int32 'atau hapus properti IsNullable dari atribut XmlElement. "
[Serializable]
[System.Xml.Serialization.XmlRoot("Score", Namespace = "http://mycomp.com/test/score/v1")]
public class Score
{
private int? iID_m;
...
/// <summary>
///
/// </summary>
public int? ID
{
get
{
return iID_m;
}
set
{
iID_m = value;
}
}
...
}
Kelas di atas akan berseri menjadi:
<Score xmlns="http://mycomp.com/test/score/v1">
<ID xsi:nil="true" />
</Score>
Tetapi untuk ID yang null saya tidak menginginkan elemen ID sama sekali, terutama karena ketika saya menggunakan OPENXML di MSSQL, ia mengembalikan 0, bukan null untuk elemen yang terlihat seperti
sumber
HasValue
properti.Foo
Anda juga memiliki apublic bool FooSpecified {get {...} set {...}}
, makaget
digunakan untuk melihat apakahFoo
harus diserialisasi, danset
dipanggil saat menetapkan nilaiFoo
selama deserialisasi.Saya menggunakan pola mikro ini untuk mengimplementasikan serialisasi 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; } }
Ini menyediakan antarmuka yang tepat untuk pengguna tanpa kompromi dan masih melakukan hal yang benar saat membuat serial.
sumber
Saya menemukan solusi dengan memanfaatkan dua properti. Sebuah int? properti dengan atribut XmlIgnore dan properti objek yang berseri.
/// <summary> /// Score db record /// </summary> [System.Xml.Serialization.XmlIgnore()] public int? ID { get { return iID_m; } set { iID_m = value; } } /// <summary> /// Score db record /// </summary> [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()); } } }
sumber
Wow terima kasih pertanyaan / jawaban ini sangat membantu saya. Saya menyukai Stackoverflow.
Saya membuat apa yang Anda lakukan di atas sedikit lebih umum. Yang benar-benar kami cari adalah memiliki Nullable dengan perilaku serialisasi yang sedikit berbeda. Saya menggunakan Reflector untuk membangun Nullable saya sendiri, dan menambahkan beberapa hal di sana-sini untuk membuat serialisasi XML bekerja seperti yang kita inginkan. Sepertinya bekerja dengan cukup baik:
public class Nullable<T> { 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<T> i_value) { return i_value.Value; } public static implicit operator Nullable<T>(T i_value) { return new Nullable<T>(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; }
Anda kehilangan kemampuan untuk menjadikan anggota Anda sebagai int? dan seterusnya (sebagai gantinya harus menggunakan Nullable <int>) tetapi selain itu semua perilaku tetap sama.
sumber
System.ExecutionEngineException
padaXmlSerializer.Serialize
saya.Sayangnya, perilaku yang Anda gambarkan secara akurat didokumentasikan seperti itu dalam dokumen untuk XmlElementAttribute.IsNullable.
sumber
Posting yang sangat berguna sangat membantu.
Saya memilih untuk menggunakan revisi Scott ke tipe data Nullable (Of T), namun kode yang diposting masih membuat serial elemen Nullable ketika itu adalah Null - meskipun tanpa atribut "xs: nil = 'true'".
Saya perlu memaksa serializer untuk menjatuhkan tag sepenuhnya jadi saya cukup menerapkan IXmlSerializable pada struktur (ini ada di VB tetapi Anda mendapatkan gambarnya):
'---------------------------------------------------------------------------- ' GetSchema '---------------------------------------------------------------------------- Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema Return Nothing End Function '---------------------------------------------------------------------------- ' ReadXml '---------------------------------------------------------------------------- Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml If (Not reader.IsEmptyElement) Then If (reader.Read AndAlso reader.NodeType = System.Xml.XmlNodeType.Text) Then Me._value = reader.ReadContentAs(GetType(T), Nothing) End If End If End Sub '---------------------------------------------------------------------------- ' WriteXml '---------------------------------------------------------------------------- Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml If (_hasValue) Then writer.WriteValue(Me.Value) End If End Sub
Saya lebih suka metode ini untuk menggunakan pola (foo) Ditentukan karena itu memerlukan penambahan muatan ember properti yang berlebihan ke objek saya, sedangkan menggunakan tipe Nullable baru hanya memerlukan pengetikan ulang properti.
sumber