2008-10-28 14 views
81

Serialize मेरे पास एक कक्षा के साथ एक कक्षा है? डेटाटाइप एक एक्सएमएल तत्व के रूप में serialize करने के लिए सेट। क्या इसे सेट अप करने का कोई तरीका है ताकि एक्सएमएल सीरियलाइज़र तत्व को क्रमबद्ध नहीं करेगा यदि मान शून्य है?एक nullable int

मैं, [System.Xml.Serialization.XmlElement (IsNullable = false)] विशेषता जोड़ने की कोशिश की है, लेकिन मैं एक क्रम क्रमबद्धता अपवाद कह एक एक प्रकार को दर्शाती त्रुटि थी मिलता है क्योंकि "IsNullable नहीं हो सकता है एक शून्य प्रकार के लिए 'झूठी' पर सेट करें। 'System.Int32' प्रकार का उपयोग करने या XmlElement विशेषता से IsNullable प्रॉपर्टी को हटाने पर विचार करें। "

[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; 
     } 
    } 
    ... 
} 

ऊपर वर्ग को क्रमानुसार जाएगा:

<Score xmlns="http://mycomp.com/test/score/v1"> 
    <ID xsi:nil="true" /> 
</Score> 

लेकिन आईडी अशक्त मैं आईडी तत्व बिल्कुल नहीं करना चाहते, क्योंकि मुख्य रूप से जब मैं MSSQL में OPENXML का उपयोग कर रहे हैं के लिए, यह एक रिटर्न 0

उत्तर

139

XmlSerializer, ShouldSerialize{Foo}() पैटर्न का समर्थन करता है।

+8

XmlSerializer भी [Foo} निर्दिष्ट पैटर्न का समर्थन करता है। –

+23

रिलेवेंट पेज यहां है: http://msdn.microsoft.com/en-us/library/53b8022e%28VS.71%29.aspx – cbp

+1

ऑटो-जेनरेटेड गुणों के साथ का उपयोग करने के लिए कोई तरीका? यानी कोई स्थानीय चर नहीं। – Jay

1

दुर्भाग्यवश, आपके द्वारा वर्णित व्यवहार XmlElementAttribute.IsNullable के दस्तावेज़ों में सटीक रूप से दस्तावेज किए गए तत्व के लिए शून्य के बजाय 0 है।

12

मैं एक समाधान के दो गुण का उपयोग पता लगा। एक इंट? XmlIgnore विशेषता और एक ऑब्जेक्ट प्रॉपर्टी के साथ संपत्ति जो क्रमबद्ध हो जाती है। यकीन नहीं XmlSerializer है कि एक का समर्थन करता है -

public bool ShouldSerializeID() {return ID.HasValue;} 

भी {Foo}Specified पैटर्न नहीं है: तो तुम एक विधि जोड़ सकते हैं

/// <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()); 
      } 
     } 
    } 
+0

यह समाधान बहुत अच्छा है क्योंकि यह ग्राहकों को ग्राहकों के लिए "प्लेसहोल्डर" मान के रूप में एन्कोड करने की अनुमति देता है, जो इनलेट्स, यानी फ्लेक्स में एनयूएलएल को नहीं पहचानते हैं। –

6

वाह धन्यवाद इस प्रश्न/उत्तर वास्तव में मुझे बाहर में मदद की। मैं दिल Stackoverflow।

मैं क्या आप एक छोटे से अधिक सामान्य से ऊपर कर रहे हैं बनाया है। हम वास्तव में खोज रहे हैं कि थोड़ा अलग क्रमबद्ध व्यवहार के साथ न्यूलबल होना है। मैंने अपने स्वयं के नलबल बनाने के लिए परावर्तक का उपयोग किया, और एक्सएमएल क्रमबद्धता को जिस तरीके से हम चाहते हैं, वहां काम करने के लिए यहां कुछ और चीजें जोड़ दीं। बहुत अच्छी तरह से काम करने लगता है:

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

आप अपने सदस्यों को int के रूप में रखने की क्षमता खो देते हैं? और इसी तरह (इसके बजाय Nullable <int> का उपयोग करना होगा) लेकिन इसके अलावा सभी व्यवहार समान रहता है।

+1

यह मुझ पर 'XmlSerializer.Serialize' पर 'System.ExecutionEngineException' फेंकता है। – modiX

23

मैं 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; } } 

यह समझौता बिना उपयोगकर्ता को सही इंटरफेस प्रदान करता है और अभी भी सही बात है जब serializing करता है।

+1

के बाद से SomeValue अशक्त हो सकता है ... सार्वजनिक डबल XmlSomeValue {{मिल SomeValue.HasValue वापसी? कुछ वैल्यू। वैल्यू: 0; } सेट {SomeValue = मान; }} –

+0

XmlSomeValue केवल XmlSerializer केवल इसे छूने करेंगे जो जब XmlSomeValueSpecified सच है द्वारा इस्तेमाल किया जा माना जाता है (यानी SomeValue.Value रिक्त नहीं है –

+5

सकल, लेकिन यह चाल किया +1 – pettys

1

बहुत उपयोगी पोस्टिंग ने एक बड़ा सौदा करने में मदद की।

मैंने स्कॉट के नलबल (टी) डेटाटाइप में संशोधन के साथ जाने का विकल्प चुना, हालांकि कोड पोस्ट अभी भी नलबल तत्व को क्रमबद्ध करता है जब यह शून्य है - यद्यपि "xs: nil = 'true'" विशेषता के बिना।(का उपयोग करने के

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

मैं इस विधि पसंद करते हैं:

मैं (इस VB में है, लेकिन आप चित्र प्राप्त) संरचना पर टैग पूरी तरह से तो मैं बस कार्यान्वित IXmlSerializable ड्रॉप करने serializer के लिए मजबूर करने की जरूरत है foo) निर्दिष्ट पैटर्न के रूप में, जिसमें मेरी ऑब्जेक्ट्स को अनावश्यक गुणों के बाल्टी लोड जोड़ने की आवश्यकता होती है, जबकि नए नलबल प्रकार का उपयोग करने के लिए केवल गुणों को पुनः टाइप करने की आवश्यकता होती है।

संबंधित मुद्दे