c# - XmlSerializer-प्रकार को प्रतिबिंबित करने में त्रुटि हुई थी




.net serialization (11)

[System.Xml.Serialization.XmlElementAttribute ("strFieldName", फॉर्म = System.Xml.Schema.XmlSchemaForm.Unqualified)]

// या

[XmlIgnore] स्ट्रिंग [] strFielsName {get; set;}

सी # .NET 2.0 का उपयोग करके, मेरे पास एक समग्र डेटा क्लास है जिसमें उस पर [Serializable] विशेषता है। मैं एक XMLSerializer वर्ग बना रहा हूं और इसे निर्माता में पास कर रहा हूं:

XmlSerializer serializer = new XmlSerializer(typeof(DataClass));

मुझे एक अपवाद मिल रहा है:

प्रकार को प्रतिबिंबित करने में त्रुटि हुई थी।

डेटा वर्ग के अंदर एक और समग्र वस्तु है। क्या इसे [Serializable] विशेषता भी है, या इसे शीर्ष ऑब्जेक्ट पर रखने की आवश्यकता है, क्या यह इसे फिर से सभी ऑब्जेक्ट्स पर लागू करता है?


आप जो आंतरिक अपवाद प्राप्त कर रहे हैं उसे देखें। यह आपको बताएगा कि किस क्षेत्र / संपत्ति को क्रमबद्ध करने में परेशानी हो रही है।

आप [XmlIgnore] विशेषता के साथ सजाने के द्वारा xml serialization से फ़ील्ड्स / गुणों को बहिष्कृत कर सकते हैं।

मुझे नहीं लगता कि XmlSerializer [Serializable] विशेषता का उपयोग करता है, इसलिए मुझे संदेह है कि यह समस्या है।


क्रमबद्धता ग्राफ में सभी ऑब्जेक्ट्स को क्रमबद्ध होना चाहिए।

चूंकि XMLSerializer एक ब्लैकबॉक्स है, इसलिए यदि आप धारावाहिक प्रक्रिया में आगे डीबग करना चाहते हैं तो इन लिंक को जांचें ..

XmlSerializer आउटपुट अस्थायी असेंबली जहां बदल रहा है

कैसे करें: एक .NET XmlSerializer जेनरेटेड असेंबली में डीबग करें


मुझे एक ही समस्या थी, और यह पता चला कि धारावाहिक एक ही नाम के साथ 2 वर्गों के बीच अंतर नहीं कर सका (एक दूसरे का उप-वर्ग था)। आंतरिक अपवाद इस तरह दिखता था:

'बेस नेमस्पेस.क्लास 1' और 'बेस नेमस्पेस। सबनामस्पेस.क्लास 1' दोनों एक्सएमएल टाइप नाम, 'कक्षा 1', नामस्थान से '' का उपयोग करते हैं। प्रकार के लिए एक अद्वितीय एक्सएमएल नाम और / या नेमस्पेस निर्दिष्ट करने के लिए एक्सएमएल विशेषताओं का उपयोग करें।

जहां BaseNamespace.SubNamespace.Class1 बेस नामस्थान का क्लास है। क्लास 1।

मुझे जो करना है वह कक्षाओं में से एक को जोड़ना था (मैंने बेस क्लास में जोड़ा):

[XmlType("BaseNamespace.Class1")]

नोट: यदि आपके पास कक्षाओं की अधिक परतें हैं तो आपको उन्हें एक विशेषता जोड़ने की आवश्यकता है।


मेरी एक ऐसी स्थिति थी जहां एक पंक्ति में दो तत्वों के लिए आदेश समान था

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]

.... कुछ कोड ...

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]

जब मैंने कक्षा में प्रत्येक नई संपत्ति के लिए आदेश को बढ़ाने के लिए कोड बदल दिया, तो त्रुटि दूर हो गई।


मेरे द्वारा सबसे आम कारण:

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members

मैं अपने डोमेन वर्गों को क्रमबद्ध करने के लिए NetDataSerialiser क्लास का उपयोग कर रहा हूं। NetDataContractSerializer कक्षा

डोमेन वर्ग क्लाइंट और सर्वर के बीच साझा किए जाते हैं।


मैंने पाया है कि .NET 2.0 में डिक्शनरी क्लास एक्सएमएल का उपयोग करके क्रमबद्ध नहीं है, लेकिन बाइनरी सीरियलाइजेशन का उपयोग होने पर अच्छी तरह से क्रमबद्ध होता है।

मुझे here एक काम मिला।


यदि आपको विशिष्ट विशेषताओं (यानी शब्दकोश, या किसी भी वर्ग) को संभालने की आवश्यकता है, तो आप IXmlSerialiable इंटरफ़ेस को कार्यान्वित कर सकते हैं, जो आपको अधिक वर्बोज कोडिंग की लागत पर अधिक स्वतंत्रता प्रदान करेगा

public class NetService : IXmlSerializable
{
    #region Data

        public string Identifier = String.Empty;

        public string Name = String.Empty;

        public IPAddress Address = IPAddress.None;
        public int Port = 7777;

    #endregion

    #region IXmlSerializable Implementation

        public XmlSchema GetSchema() { return (null); }

        public void ReadXml(XmlReader reader)
        {
            // Attributes
            Identifier = reader[XML_IDENTIFIER];
            if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
            if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
        }

        public void WriteXml(XmlWriter writer)
        {
            // Attributes
            writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
            writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
            writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
        }

        private const string XML_IDENTIFIER = "Id";

        private const string XML_NETWORK_ADDR = "Address";

        private const string XML_NETWORK_PORT = "Port";

    #endregion
}

एक दिलचस्प article , जो XmlSerializer को "विस्तारित" करने के लिए एक परिष्कृत तरीका लागू करने का एक शानदार तरीका दिखाता है।

लेख कहता है:

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

क्योंकि, मैं आपको बहुत जटिल कार्यान्वयन से बचने के लिए, अपने स्वयं के IXmlSerializable वर्गों को लागू करने का सुझाव देता हूं।

... प्रतिबिंब का उपयोग कर हमारे कस्टम XmlSerializer वर्ग को लागू करने के लिए यह सीधा हो सकता है।


यह भी ध्यान रखें कि XmlSerializer अमूर्त गुणों को क्रमबद्ध नहीं कर सकता .. मेरा प्रश्न here देखें (जिसे मैंने समाधान कोड जोड़ा है) ..

here


याद रखें कि क्रमबद्ध कक्षाओं में डिफ़ॉल्ट होना चाहिए (यानी पैरामीटर रहित) रचनाकार। यदि आपके पास कोई कन्स्ट्रक्टर नहीं है, तो यह ठीक है; लेकिन अगर आपके पास पैरामीटर वाला कन्स्ट्रक्टर है, तो आपको डिफ़ॉल्ट भी जोड़ना होगा।





.net-2.0