XmlSerializer - एक चिंतनशील प्रकार था


332

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

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

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

टाइप करने में त्रुटि हुई।

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

जवाबों:


413

भीतर के अपवाद को देखें जो आपको मिल रहा है। यह आपको बताएगा कि किस फील्ड / प्रॉपर्टी को सीरियल करने में परेशानी हो रही है।

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

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


11
मेरी वस्तु में उरी क्षेत्र था, जो इस अपवाद का कारण बना; उरी वर्ग में एक पैरामीटर रहित निर्माता नहीं है। पारितोषिक के लिए धन्यवाद।
ford

10
एक Google खोज के साथ इस पर आया था - मेरा विशेष मुद्दा मेरी "सीरियलाइज्ड" श्रेणी में एक संपत्ति थी, IListजब इसे होने की आवश्यकता थी List
पॉल एल्ड्रेड-बान

7
एक "आंतरिक अपवाद" को कैसे देखता है?
डेविड

7
या '@ एक्ससेप्शन' को एक घड़ी में जोड़ें
arolson101

19
धन्यवाद, इस जवाब ने मेरी मदद की। मैंने शुरू में आंतरिक अपवाद को देखा, और मुख्य वर्ग का उल्लेख करते हुए देखा। लेकिन मैंने महसूस किया कि मैं सहज ज्ञान की धारणाओं में ढल सकता हूं, और आखिरकार, 5 स्तर नीचे, मुझे मुद्दा मिल गया। मेरे पास कक्षाएं थीं जो परस्पर विरोधी थीं। धन्यवाद।
लुई वैन टोनर

111

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


4
याद दिलाने के लिए शुक्रिया! मुझे नफरत है कि यह एक स्पष्टीकरण के साथ एक रनटाइम त्रुटि है।
जारेड अपडेटाइक

मैं बार-बार यह गलती करता रहता हूं। एक पैरामीटर रहित निर्माता का उपयोग करने की याद दिलाने के लिए धन्यवाद ^ ^
aZtraL-EnForceR

25

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

'प्रकार BaseNamespace.Class1' और 'BaseNamespace। प्रकार के लिए एक विशिष्ट XML नाम और / या नाम स्थान निर्दिष्ट करने के लिए XML विशेषताओं का उपयोग करें।

जहां BaseNamespace.SubNamespace.Class1 BaseNamespace.Class1 का एक उपवर्ग है।

मुझे इसमें से एक वर्ग में एक विशेषता जोड़ने की आवश्यकता थी (मैंने आधार वर्ग में जोड़ा):

[XmlType("BaseNamespace.Class1")]

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


इसने मेरे लिए समस्या को ठीक किया, धन्यवाद, +1; मेरे पास कई प्रोसेसर * ऑब्जेक्ट्स के साथ एक समान सेटिंग थी, हर एक कॉन्फिगर इनर क्लास के साथ। रनटाइम SomeNS.Processor1.Config और SomeNS.Processor2.Config के बीच अंतर करने में सक्षम नहीं था।
दामिक्स


6

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

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

5

क्रमांकन ग्राफ में सभी वस्तुओं को क्रमबद्ध करना होगा।

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

जहां XmlSerializer आउटपुट अस्थाई विधानसभाओं को बदल रहा है

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


5

यदि आपको विशिष्ट विशेषताओं (यानी शब्दकोश, या किसी भी वर्ग) को संभालने की आवश्यकता है, तो आप 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
}

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


लेख कहता है:

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

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

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


4

मुझे पता चला है कि .net 2.0 में डिक्शनरी क्लास XML का उपयोग करके क्रमिक नहीं है, लेकिन बाइनरी क्रमांकन का उपयोग करने पर अच्छी तरह से सीरियल करता है।

मुझे यहां चारों ओर एक काम मिला ।


3

मुझे हाल ही में एक नई संपत्ति जोड़ते समय एक वेब संदर्भ आंशिक वर्ग में मिला। ऑटो उत्पन्न वर्ग निम्नलिखित विशेषताओं को जोड़ रहा था।

    [System.Xml.Serialization.XmlElementAttribute(Order = XX)]

मुझे ऑटो जेनरेट किए गए सीक्वेंस में पिछले की तुलना में एक आर्डर के साथ एक समान विशेषता जोड़ने की जरूरत थी और इसने मेरे लिए इसे ठीक कर दिया।


3

मुझे बस एक ही त्रुटि मिली और पता चला कि प्रकार की संपत्ति IEnumerable<SomeClass>समस्या थी। ऐसा प्रतीत होता है कि IEnumerableइसे सीधे प्रसारित नहीं किया जा सकता है।

इसके बजाय, कोई भी उपयोग कर सकता है List<SomeClass>


2

मैंने यह भी सोचा था कि सीरियल करने योग्य विशेषता वस्तु पर होनी थी, लेकिन जब तक कि मैं पूर्ण नोब नहीं हो जाता (मैं एक देर रात कोडिंग सत्र के बीच में हूं) स्निपेटकॉमपाइलर से निम्न कार्य करता है :

using System;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Xml.Serialization;

public class Inner
{
    private string _AnotherStringProperty;
    public string AnotherStringProperty 
    { 
      get { return _AnotherStringProperty; } 
      set { _AnotherStringProperty = value; } 
    }
}

public class DataClass
{
    private string _StringProperty;
    public string StringProperty 
    { 
       get { return _StringProperty; } 
       set{ _StringProperty = value; } 
    }

    private Inner _InnerObject;
    public Inner InnerObject 
    { 
       get { return _InnerObject; } 
       set { _InnerObject = value; } 
    }
}

public class MyClass
{

    public static void Main()
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
            TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml");
            DataClass clazz = new DataClass();
            Inner inner = new Inner();
            inner.AnotherStringProperty = "Foo2";
            clazz.InnerObject = inner;
            clazz.StringProperty = "foo";
            serializer.Serialize(writer, clazz);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

}

मुझे लगता है कि XmlSerializer सार्वजनिक संपत्तियों पर प्रतिबिंब का उपयोग कर रहा है।


1

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

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

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

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

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


1

मुझे एक ही त्रुटि मिल रही थी जब मैंने एक डेटाटाइप होने वाली संपत्ति बनाई थी - Type। इस पर, मुझे एक त्रुटि मिल रही थी - टाइप करने में त्रुटि हुई। मैं डिबग गोदी से हर अपवाद के 'इनर एक्सेप्शन' की जांच करता रहा और Typeमेरे मामले में विशिष्ट फ़ील्ड नाम (जो था ) मिला। समाधान इस प्रकार है:

    [XmlIgnore]
    public Type Type { get; set; }

0

यह भी ध्यान दें कि आप उपयोगकर्ता इंटरफ़ेस नियंत्रणों को क्रमबद्ध नहीं कर सकते हैं और क्लिपबोर्ड पर आप जिस किसी भी ऑब्जेक्ट को पास करना चाहते हैं, वह धारावाहिक होना चाहिए अन्यथा इसे अन्य प्रक्रियाओं में पार नहीं किया जा सकता है।



0

मेरे पास एक ही मुद्दा था और मेरे मामले में ऑब्जेक्ट में ReadOnlyCollection था। एक संग्रह क्रमबद्ध होने के लिए ऐड मेथड को लागू करना चाहिए।


यह सवाल का उचित जवाब नहीं है। इस प्रश्न पर अन्य 15 उत्तर पहले से ही हैं। अगर आपको लगता है कि आपका जवाब दूसरों की तुलना में बेहतर है, तो आपको इसके बारे में अधिक जानकारी प्रदान करनी चाहिए। कुछ कोड और आउटपुट स्निपेट प्रदान करना हमेशा उपयोगकर्ताओं की मदद करता है। अपने उत्तर पोस्ट करने से पहले पढ़ने पर विचार करें -> stackoverflow.com/help/how-to-answer
अमित फलतानकर

0

मेरे पास अब तक वर्णित सभी के लिए थोड़ा अलग समाधान है, इसलिए किसी भी भविष्य की सभ्यता के लिए यहां मेरा है!

मैंने "समय" के एक प्रारूप को घोषित किया था क्योंकि मूल प्रकार एक था TimeSpanऔर बाद में इसे बदल दिया गया String:

[System.Xml.Serialization.XmlElementAttribute(DataType="time", Order=3)]

हालांकि वास्तविक प्रकार एक स्ट्रिंग था

public string TimeProperty {
    get {
        return this.timePropertyField;
    }
    set {
        this.timePropertyField = value;
        this.RaisePropertyChanged("TimeProperty");
    }
}

DateTypeसंपत्ति को हटाकर Xmlक्रमबद्ध किया जा सकता है

[System.Xml.Serialization.XmlElementAttribute(Order=3)]
public string TimeProperty {
    get {
        return this.timePropertyField;
    }
    set {
        this.timePropertyField = value;
        this.RaisePropertyChanged("TimeProperty");
    }
}

0
[System.Xml.Serialization.XmlElementAttribute("strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

या

[XmlIgnore]
string [] strFielsName {get;set;}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.