এক্সএমএলসিরাইজার - প্রকার প্রতিবিম্বিত করতে একটি ত্রুটি হয়েছিল


332

সি # .NET 2.0 ব্যবহার করে, আমার কাছে একটি যৌগিক ডেটা ক্লাস রয়েছে যাতে এতে [Serializable]বৈশিষ্ট্য রয়েছে। আমি একটি XMLSerializerক্লাস তৈরি করছি এবং এটি কনস্ট্রাক্টরে পাস করছি:

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

আমি এই বলে ব্যতিক্রম পাচ্ছি:

প্রকার প্রতিবিম্বিত করতে একটি ত্রুটি হয়েছিল।

ডেটা ক্লাসের ভিতরে আরও একটি যৌগিক অবজেক্ট রয়েছে। এরও কি [Serializable]এট্রিবিউট থাকা দরকার, বা উপরের অবজেক্টে থাকার পরেও কি এটিকে পুনরুক্তরূপে ভিতরে সমস্ত বস্তুতে প্রয়োগ করা হয়?

উত্তর:


413

আপনি যে অভ্যন্তরীণ ব্যতিক্রম পাচ্ছেন তা দেখুন। এটি আপনাকে বলবে যে কোন ক্ষেত্র / সম্পত্তিটি ক্রমিকায়িত করতে সমস্যা হচ্ছে।

আপনি এক্সটিএমএল সিরিয়ালাইজেশন থেকে ক্ষেত্রগুলি / বৈশিষ্ট্যগুলিকে বৈশিষ্ট্যের সাথে সজ্জিত করে বাদ দিতে পারেন [XmlIgnore]

XmlSerializer[Serializable]বৈশিষ্ট্যটি ব্যবহার করে না , তাই আমি সন্দেহ করি এটিই সমস্যা।


11
আমার অবজেক্টে একটি উরি ক্ষেত্র ছিল, যা এই ব্যতিক্রম ঘটায়; উরি ক্লাসে প্যারামিটারলেস কনস্ট্রাক্টর নেই। ভকভগক.
ফোর্ড

10
একটি গুগল অনুসন্ধানের সাথে এটি জুড়ে এসেছিল - আমার নির্দিষ্ট ইস্যুতে আমার "সিরিয়ালিয়াল হতে" শ্রেণিতে একটি সম্পত্তি ছিল IListযখন এটি হওয়া দরকার List
পল আলেদ্রেড-ব্যান

7
কীভাবে একজন "অভ্যন্তরীণ ব্যতিক্রম" দেখছেন?
ডেভিড

7
বা একটি ঘড়িতে '@ এক্সপেকশন' যুক্ত করুন
arolson101

19
ধন্যবাদ, এই উত্তরটি আমাকে সাহায্য করেছে। আমি প্রাথমিকভাবে অভ্যন্তরীণ ব্যতিক্রমের দিকে তাকিয়েছিলাম, এবং কেবলমাত্র প্রধান বর্গের উল্লেখ দেখেছি। তবে আমি বুঝতে পেরেছিলাম যে আমি অনুমানের অলক্ষিত ধারণাগুলি নিয়ে যেতে পারি এবং অবশেষে, 5 টি স্তর নীচে, আমি বিষয়টি খুঁজে পেয়েছি। আমার ক্লাস ছিল যেগুলি পরস্পরবিরোধী ছিল। ধন্যবাদ।
লুই ভ্যান টন্ডার

111

মনে রাখবেন সিরিয়ালযুক্ত শ্রেণিতে অবশ্যই ডিফল্ট (অর্থাত্ প্যারামিটারলেস) কনস্ট্রাক্টর থাকতে হবে। আপনার যদি কোনও নির্মাণকারী না থাকে তবে তা ঠিক আছে; তবে আপনার যদি প্যারামিটার সহ কোনও কনস্ট্রাক্টর থাকে তবে আপনাকে ডিফল্টটিও যুক্ত করতে হবে।


4
অনুস্মারকটির জন্য ধন্যবাদ! আমি ঘৃণা করি যে এটি একটি সামান্য ব্যাখ্যা সহ একটি রানটাইম ত্রুটি।
জ্যারেড আপডেটিকে

আমি বার বার এই ভুল করতে থাকি। আমাকে স্মরণ একটি parameterless কন্সট্রাকটর ^^ ব্যবহার করার জন্য ধন্যবাদ
aZtraL-বলপ্রয়োগকারী

25

আমারও একই রকম সমস্যা ছিল এবং এটি প্রমাণিত হয়েছিল যে সিরিয়ালাইজারটি একই নামটি নিয়ে আমার 2 টি শ্রেণীর মধ্যে পার্থক্য করতে পারে না (একটি ছিল অন্যটির একটি সাবক্লাস)। অভ্যন্তরীণ ব্যতিক্রমগুলি দেখতে এই রকম ছিল:

'টাইপ বেসনেমস্পেস.ক্লাস 1' এবং 'বেসনেমস্পেস.সুবনেমস্পেস.ক্লাস 1' উভয়ই নেমস্পেস থেকে এক্সএমএল টাইপ নাম, 'ক্লাস 1' ব্যবহার করে। ধরণের জন্য একটি অনন্য এক্সএমএল নাম এবং / অথবা নেমস্পেস নির্দিষ্ট করতে এক্সএমএল বৈশিষ্ট্যগুলি ব্যবহার করুন।

যেখানে বেসনেমস্পেস.সুবনেমস্পেস.ক্লাস 1 বেসনেমস্পেস.ক্লাস 1 এর একটি সাবক্লাস।

আমার যা করার দরকার তা হ'ল ক্লাসগুলির একটিতে একটি বৈশিষ্ট্য যুক্ত করা (আমি বেস শ্রেণিতে যুক্ত করেছি):

[XmlType("BaseNamespace.Class1")]

দ্রষ্টব্য: আপনার যদি ক্লাসগুলির আরও স্তর থাকে তবে আপনার তাদের সাথে একটি বৈশিষ্ট্যও যুক্ত করতে হবে।


এটি আমার জন্য সমস্যাটি স্থির করেছে, আপনাকে ধন্যবাদ, +1; আমার বেশ কয়েকটি প্রসেসর * অবজেক্টের সাথে একই ধরণের সেটিং ছিল, প্রত্যেকটি একটি কনফিগার অভ্যন্তর শ্রেণীর সাথে। রানটাইমটি SomeNS.Processor1.Config এবং SomeNS.Processor2.Config এর মধ্যে পার্থক্য করতে সক্ষম হয় নি।
Damix911

7

এছাড়াও সচেতন থাকুন যা XmlSerializerবিমূর্ত বৈশিষ্ট্যগুলি সিরিয়ালায়িত করতে পারে না .. আমার প্রশ্নটি এখানে দেখুন (যা আমি সমাধান কোড যুক্ত করেছি) ..

এক্সএমএল সিরিয়ালাইজেশন এবং উত্তরাধিকারী প্রকারগুলি


6

আমার দ্বারা সর্বাধিক সাধারণ কারণ:

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

5

সিরিয়ালাইজেশন গ্রাফের সমস্ত অবজেক্টকে সিরিয়ালাইজ করতে হবে।

থেকে XMLSerializer একটি ব্ল্যাকবক্স, আপনি যদি সিরিয়ালাইজেশন প্রক্রিয়াটিতে আরও ডিবাগ করতে চান তবে এই লিঙ্কগুলি চেক করুন ..

যেখানে এক্সএমএলসিরালাইজার অস্থায়ী সমাবেশগুলি আউটপুট দেয় সেখানে পরিবর্তন করা হচ্ছে

কীভাবে: একটি। নেট এক্সএমএলসিরালাইজার জেনারেটেড অ্যাসেমব্লিতে ডিবাগ করুন


5

আপনার যদি নির্দিষ্ট বৈশিষ্ট্যগুলি (যেমন অভিধান বা কোনও শ্রেণি) পরিচালনা করতে হয় তবে আপনি আইএক্সএমএলসিরিয়িয়েবল ইন্টারফেস প্রয়োগ করতে পারেন , যা আপনাকে আরও ভার্বোজ কোডিংয়ের ব্যয়ে আরও স্বাধীনতার সুযোগ দেয় ।

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
}

একটি আকর্ষণীয় নিবন্ধ রয়েছে , যা এক্সএমএলসিরালাইজারকে "প্রসারিত" করার জন্য একটি অত্যাধুনিক উপায় প্রয়োগের একটি মার্জিত উপায় দেখায়।


নিবন্ধটি বলে:

আইএক্সএমএলসিরাইজেবল অফিসিয়াল ডকুমেন্টেশনে আচ্ছাদিত, তবে ডকুমেন্টেশনে বলা হয়েছে এটি জনসাধারণের ব্যবহারের উদ্দেশ্যে নয় এবং এর বাইরে কোনও তথ্য সরবরাহ করে না। এটি ইঙ্গিত দেয় যে উন্নয়ন দলটি রাস্তার নিচে এই এক্সটেনসিবিলিটি হুকটি সংশোধন, অক্ষম করতে বা সম্পূর্ণ অপসারণের অধিকার সংরক্ষণ করতে চেয়েছিল। তবে, আপনি যতক্ষণ না এই অনিশ্চয়তা মেনে নিতে এবং ভবিষ্যতে সম্ভাব্য পরিবর্তনের সাথে মোকাবিলা করতে ইচ্ছুক হবেন, আপনি এর সদ্ব্যবহার করতে পারবেন না এমন কোনও কারণ নেই।

কারণ এটি, আমি নিজের নিজস্ব বাস্তবায়নের পরামর্শ দিই IXmlSerializable অত্যধিক জটিল বাস্তবায়ন এড়াতে শ্রেণি ।

... XmlSerializerপ্রতিবিম্ব ব্যবহার করে আমাদের কাস্টম ক্লাস প্রয়োগ করা সহজবোধ্য হতে পারে ।


4

আমি আবিষ্কার করেছি যে .NET 2.0 এ ডিকশনারি ক্লাসটি এক্সএমএল ব্যবহার করে সিরিয়ালাইজযোগ্য নয়, বাইনারি সিরিয়ালাইজেশন ব্যবহার করার সময় সিরিয়ালটি ভাল হয়।

আমি কাছাকাছি একটি কাজ পাওয়া এখানে


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

}

আমি কল্পনা করব যে এক্সএমএলসিরাইজার জনসাধারণের সম্পত্তিগুলির উপর প্রতিচ্ছবি ব্যবহার করছে।


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

আমার একই সমস্যা ছিল এবং আমার ক্ষেত্রে অবজেক্টটির একটি ReadOnly Colલેક્શન ছিল। ক্রিয়াকলাপযোগ্য হওয়ার জন্য কোনও সংগ্রহ অবশ্যই অ্যাড পদ্ধতি প্রয়োগ করবে।


এটি প্রশ্নের সঠিক উত্তর নয়। এই প্রশ্নের উপর অন্য 15 টি উত্তর ইতিমধ্যে রয়েছে। আপনি যদি মনে করেন যে আপনার উত্তরটি অন্যের চেয়ে ভাল তবে আপনার এটি সম্পর্কে আরও বিশদ সরবরাহ করা উচিত। কিছু কোড এবং আউটপুট স্নিপেট সরবরাহ সর্বদা ব্যবহারকারীদের সহায়তা করে। আপনার উত্তর পোস্ট করার আগে পড়া বিবেচনা -> stackoverflow.com/help/how-to-answer
অমিত Phaltankar

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সিরিয়াল করা যেতে পারে can

[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;}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.