.নেট এক্সএমএল সিরিয়ালাইজেশন গেটস? [বন্ধ]


121

সি # এক্সএমএল সিরিয়ালাইজেশন করার সময় আমি কয়েকটি গোছা হয়েছি যা ভেবেছিলাম ভাগ করে নিলাম:

  • আপনি কেবল পঠনযোগ্য আইটেমগুলিকে সিরিয়ালাইজ করতে পারবেন না (যেমন কীভ্যালিউপায়ার্স)
  • আপনি একটি জেনেরিক অভিধান সিরিয়াল করতে পারবেন না। পরিবর্তে, এই মোড়কের ক্লাসটি ব্যবহার করে দেখুন ( http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx থেকে ):

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

[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{      
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");

            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            this.Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
}

অন্য কোনও এক্সএমএল সিরিয়ালাইজেশন আছে?


: আরও gotchas জন্য Lookin তোমার, আপনি আমাকে সাহায্য করতে সক্ষম হতে পারেন stackoverflow.com/questions/2663836/...
কামিজ Weitzhandler

1
এছাড়াও, আপনি serialzable অভিধানের চার্লস Feduke বাস্তবায়ন করার জন্য একটি কটাক্ষপাত করতে চাইবেন, তিনি নিয়মিত সদস্য বিশেষণীয় সদস্যদের মধ্যে বিজ্ঞপ্তির XML লেখক তৈরি ডিফল্ট serializer দ্বারা ধারাবাহিকভাবে হবে: deploymentzone.com/2008/09/19/...
শিমি ওয়েটজ্যান্ডলার

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

উত্তর:


27

আরেকটি বিশাল গোচা: ওয়েব পৃষ্ঠার মাধ্যমে এক্সএমএল আউটপুট দেওয়ার সময় (এএসপি.এনইটি), আপনি ইউনিকোড বাইট-অর্ডার চিহ্নটি অন্তর্ভুক্ত করতে চান না । অবশ্যই, বিওএম ব্যবহার বা ব্যবহার না করার উপায়গুলি প্রায় একই রকম:

বিএডি (বিওএম অন্তর্ভুক্ত):

XmlTextWriter wr = new XmlTextWriter(stream, new System.Text.Encoding.UTF8);

ভাল:

XmlTextWriter  wr = new XmlTextWriter(stream, new System.Text.UTF8Encoding(false))

আপনি বিওএম চান না তা বোঝাতে আপনি স্পষ্টভাবে মিথ্যা পাস করতে পারেন। লক্ষ্য করুন মধ্যে পরিষ্কার, সুস্পষ্ট পার্থক্য Encoding.UTF8এবং UTF8Encoding

শুরুতে অতিরিক্ত তিনটি বিওএম বাইট হ'ল (0xEFBBBF) বা (239 187 191)।

তথ্যসূত্র: http://chrislaco.com/blog/troubleshooting-common-problems-with-the-xmlserializer/


4
আপনার মন্তব্যটি আরও কার্যকর হবে যদি আপনি আমাদের কেবল কী না, তবে কেন জানান।
নীল

1
এটি আসলে এক্সএমএল সিরিয়ালাইজেশনের সাথে সম্পর্কিত নয় ... এটি কেবলমাত্র একটি এক্সএমএল টেক্সট রাইটার সমস্যা
টমাস

7
-1: প্রশ্নের সাথে সম্পর্কিত নয় এবং আপনার XmlTextWriter.NET 2.0 বা ততোধিক ব্যবহার করা উচিত নয় ।
জন স্যান্ডার্স

খুব সহায়ক রেফারেন্স লিঙ্ক। ধন্যবাদ।
অনিল ভঙ্গারি

21

আমি এখনও মন্তব্য করতে পারি না, তাই আমি Dr8k এর পোস্টে মন্তব্য করব এবং অন্য একটি পর্যবেক্ষণ করব। প্রাইভেট ভেরিয়েবলগুলি যেগুলি পাবলিক গেটর / সেটার বৈশিষ্ট্য হিসাবে প্রকাশিত হয় এবং সেই বৈশিষ্ট্যগুলির মাধ্যমে সিরিয়ালযুক্ত / deserialized হয়। আমরা এটি আমার পুরানো কাজটি সময়ে করেছি।

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

আমি অতীতে এই দ্বারা পোড়া হয়েছে।


17
ক্ষেত্রের ক্রম সুস্পষ্টভাবে সেট করার উপায় অনুসন্ধান করার সময় আমি এই পোস্টটি পেয়েছি। এটি বৈশিষ্ট্যগুলির সাথে সম্পন্ন করা হয়: [এক্সএমএলএলমেন্টএট্রিবিউট (অর্ডার = 1)] পাবলিক ইন ফিল্ড {...} ডাউনসাইড: গুণটি অবশ্যই শ্রেণীর সমস্ত ক্ষেত্র এবং তার সমস্ত বংশধরের জন্য নির্দিষ্ট করতে হবে! IMO আপনার এটি আপনার পোস্টে যুক্ত করা উচিত।
ক্রিশ্চিয়ান ডায়াকোনস্কু

15

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

http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer(VS.80).aspx


3
ডকস থেকে সরাসরি "নোট করুন বাফারটিতে বরাদ্দকৃত বাইট রয়েছে যা অব্যবহৃত হতে পারে For উদাহরণস্বরূপ, স্ট্রিং" টেস্ট "যদি মেমোরিস্ট্রিম অবজেক্টে লেখা হয়, গেটবফার থেকে ফিরে আসা বাফারের দৈর্ঘ্য 256 নয়, 252 বাইট সহ বাফারে কেবল ডেটা পেতে, টোআরাই পদ্ধতিটি ব্যবহার করুন; তবে টোআরাই মেমরিতে ডেটার একটি অনুলিপি তৈরি করে। " msdn.microsoft.com/en-us/library/...
realgt

শুধু এখন এই দেখেছি। আর বাজে কথা মনে হচ্ছে না।
জন স্যান্ডার্স

এটি আগে কখনও শুনেনি, যা ডিবাগিংয়ে সহায়ক।
রিকি

10

সিরিয়ালাইজার যদি কোনও সদস্য / সম্পত্তির মুখোমুখি হয় যা এর ধরণের হিসাবে একটি ইন্টারফেস রয়েছে তবে এটি সিরিয়াল হবে না। উদাহরণস্বরূপ, নিম্নলিখিতগুলি এক্সএমএলকে সিরিয়ালায়িত করবে না:

public class ValuePair
{
    public ICompareable Value1 { get; set; }
    public ICompareable Value2 { get; set; }
}

যদিও এটি সিরিয়ালাইজ হবে:

public class ValuePair
{
    public object Value1 { get; set; }
    public object Value2 { get; set; }
}

যদি আপনি "সদস্যের জন্য ধরণের সমাধান না করুন ..." বার্তাটি ব্যতিক্রম করে পান তবে যা ঘটছে তা হতে পারে।
কাইল ক্রল

9

IEnumerables<T>ফলন রিটার্নের মাধ্যমে উত্পন্ন যে ক্রিয়াকলাপযোগ্য নয়। এটি কারণ উত্পাদিত রিটার্ন বাস্তবায়নের জন্য সংকলক একটি পৃথক শ্রেণি তৈরি করে এবং সেই শ্রেণিটি সিরিয়ালযোগ্য হিসাবে চিহ্নিত হয় না।


এটি 'অন্যান্য' সিরিয়ালাইজেশন, অর্থাৎ [সিরিয়ালাইজযোগ্য] বৈশিষ্ট্যে প্রযোজ্য। যদিও এটি এক্সএমএলসিরাইজারের পক্ষে কাজ করে না।
টিম রবিনসন


8

আপনি কেবল পঠনযোগ্য বৈশিষ্ট্যগুলিকে সিরিয়ালাইজ করতে পারবেন না। আপনার অবশ্যই একটি গিটার এবং সেটার থাকতে হবে, এমনকি যদি আপনি কখনই কোনও এক্সএমএলকে এক্সএমএল রূপান্তর করতে ডিসরিয়ালাইজেশন ব্যবহার করতে চান না।

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


1
প্রকৃতপক্ষে আপনি কোনও সংগ্রাহক সম্পত্তি সিরিয়ালাইজ করতে পারেন যদিও এর কোনও সেটেটর না থাকলেও এটি কনস্ট্রাক্টরতে শুরু করতে হবে যাতে ডিসরিয়ালাইজেশন এতে আইটেম যুক্ত করতে পারে
টমাস লেভস্ক

7

ওহ এখানে একটি ভাল: যেহেতু এক্সএমএল সিরিয়ালাইজ কোডটি তৈরি করা হয়েছে এবং একটি পৃথক ডিএলএল স্থাপন করা হয়েছে, আপনার কোডটিতে কোনও ভুল আছে যা সিরিয়ালাইজারটি ভেঙে দিলে আপনি কোনও অর্থবহ ত্রুটি পাবেন না। "S3d3fsdf.dll সনাক্ত করতে অক্ষম" এর মতো কিছু। খুশী হলাম।


11
আপনি এক্সএমএল "সিরিয়ালাইজার জেনারেটর সরঞ্জাম (Sgen.exe)" ব্যবহার করে এবং আপনার অ্যাপ্লিকেশনটি দিয়ে মোতায়েন করে সময়ের আগে যে ডিএলএল তৈরি করতে পারেন।
huseyint

6

প্যারামিটারলেস কনস্ট্রিউটর না থাকা কোনও বস্তুটি সিরিয়ালাইজ করা যায় না (কেবলমাত্র এটি দ্বারা কামড়েছে)।

এবং কোনও কারণে, নিম্নলিখিত বৈশিষ্ট্যগুলি থেকে, মানটি সিরিয়ালযুক্ত হয়, তবে পুরো নাম নয়:

    public string FullName { get; set; }
    public double Value { get; set; }

আমি কখনই কাজ করার চেষ্টা করিনি কেন, আমি কেবলমাত্র মানটিকে অভ্যন্তরীণে পরিবর্তন করেছি ...


4
প্যারামিটারলেস কনস্ট্রাক্টর ব্যক্তিগত / সুরক্ষিত হতে পারে। এটি এক্সএমএল সিরিয়ালাইজের পক্ষে যথেষ্ট হবে। ফুলনামের সমস্যাটি সত্যিই অদ্ভুত, এমনটি হওয়া উচিত নয় ...
ম্যাক্স গ্যালকিন

@Yacoder: হয়তো না, কারণ double?কিন্তু double?
abatishchev

পুরো নামটি সম্ভবত ছিল nullএবং তাই সিরিয়ালযুক্ত হওয়ার পরে কোনও এক্সএমএল তৈরি করবে না
জেস্পার

5

আরও একটি বিষয় লক্ষণীয়: আপনি যদি "ডিফল্ট" এক্সএমএল সিরিয়ালাইজেশন ব্যবহার করেন তবে আপনি ব্যক্তিগত / সুরক্ষিত শ্রেণীর সদস্যদের সিরিয়ালাইজ করতে পারবেন না।

তবে আপনি আপনার ক্লাসে আইএক্সএমএল সিরিয়ালাইজেবল প্রয়োগ করে কাস্টম এক্সএমএল সিরিয়ালাইজেশন লজিক নির্দিষ্ট করতে পারেন এবং আপনার প্রয়োজন / যে কোনও প্রাইভেট ফিল্ড ক্রমযুক্ত করতে চান।

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx


4

যদি আপনার এক্সএমএল সিরিয়ালাইজেশন উত্পন্ন সমাবেশটি কোডটি ব্যবহার করার চেষ্টা করার মতো লোড প্রসঙ্গে না থাকে তবে আপনি দুর্দান্ত ভয়ঙ্কর ত্রুটিতে চলে যাবেন:

System.InvalidOperationException: There was an error generating the XML document.
---System.InvalidCastException: Unable to cast object
of type 'MyNamespace.Settings' to type 'MyNamespace.Settings'. at
Microsoft.Xml.Serialization.GeneratedAssembly.
  XmlSerializationWriterSettings.Write3_Settings(Object o)

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


4

রঙ এবং / অথবা হরফ টাইপের অবজেক্টগুলিকে সিরিয়ালাইজ করতে আপনার সমস্যার মুখোমুখি হতে পারে।

এখানে পরামর্শগুলি, যা আমাকে সহায়তা করেছিল:

http://www.codeproject.com/KB/XML/xmlsettings.aspx

http://www.codeproject.com/KB/cs/GenericXmlSerializition.aspx


4

এক্সএমএল সিরিয়ালাইজার দ্বারা কী সমর্থিত তা সম্পর্কিত বিশদ এবং সমর্থিত এক্সএসডি বৈশিষ্ট্যগুলি কীভাবে সমর্থিত সে সম্পর্কে বিশদ বিবরণের জন্য " অ্যাডভান্সড এক্সএমএল স্কিমা সংজ্ঞা ভাষা বৈশিষ্ট্যগুলি বাঁধাই সমর্থন " দেখুন।


4

আপনি একটি অ্যারের, ধারাবাহিকভাবে চেষ্টা করলে List<T>, অথবা IEnumerable<T>যার দৃষ্টান্ত রয়েছে উপশ্রেণী এর T, আপনি ব্যবহার করতে হবে XmlArrayItemAttribute লিস্টে সব উপশাখাকে ব্যবহার করা হচ্ছে। অন্যথায় আপনি System.InvalidOperationExceptionযখন সিরিয়াল করবেন তখন রানটাইমের সময় আপনি একটি অপ্রয়োজনীয় পাবেন ।

এখানে ডকুমেন্টেশন থেকে সম্পূর্ণ উদাহরণের একটি অংশ

public class Group
{  
   /* The XmlArrayItemAttribute allows the XmlSerializer to insert both the base 
      type (Employee) and derived type (Manager) into serialized arrays. */

   [XmlArrayItem(typeof(Manager)), XmlArrayItem(typeof(Employee))]
   public Employee[] Employees;

3

প্রাইভেট ভেরিয়েবল / বৈশিষ্ট্যগুলি এক্সএমএল সিরিয়ালাইজেশনের জন্য ডিফল্ট পদ্ধতিতে ক্রমিকায়িত হয় না, তবে বাইনারি সিরিয়ালাইজেশন হয়।


2
হ্যাঁ, আপনি যদি "ডিফল্ট" এক্সএমএল সিরিয়ালাইজেশন ব্যবহার করেন। আপনি আপনার ক্লাসে IXMLSerializable প্রয়োগ করে কাস্টম এক্সএমএল সিরিয়ালাইজেশন যুক্তি নির্দিষ্ট করতে পারেন এবং আপনার প্রয়োজন / যে কোনও প্রাইভেট ফিল্ড সিরিয়ালাইজ করতে পারেন।
সর্বাধিক গ্যালকিন 16

1
ঠিক আছে, এটা সত্য। আমি এটি সম্পাদনা করব। তবে সেই ইন্টারফেসটি বাস্তবায়ন করা আমার মনে পড়ার থেকে পাছার এক রকম ব্যথা।
চার্লস গ্রাহাম

3

বৈশিষ্ট্যযুক্ত চিহ্নিত Obsoleteবৈশিষ্ট্যগুলি ক্রমিক নয়। আমি Deprecatedঅ্যাট্রিবিউট দিয়ে পরীক্ষা করিনি তবে আমি ধরে নিয়েছি এটি একইভাবে কাজ করবে।


2

আমি সত্যিই এটির ব্যাখ্যা দিতে পারি না, তবে আমি পেয়েছি এটি সিরিয়াল হবে না:

[XmlElement("item")]
public myClass[] item
{
    get { return this.privateList.ToArray(); }
}

তবে এটি হবে:

[XmlElement("item")]
public List<myClass> item
{
    get { return this.privateList; }
}

এবং এটিও লক্ষণীয় যে আপনি যদি কোনও স্মৃতিচারণে সিরিয়াল করছেন তবে এটি ব্যবহার করার আগে আপনি 0 টি চাইতে চাইতে পারেন।


আমি মনে করি এটি কারণ এটি এটি পুনর্নির্মাণ করতে পারে না। দ্বিতীয় উদাহরণে এটি আইটেমটি কল করতে পারে items তালিকায় আইটেম যুক্ত করতে () যুক্ত করুন। এটি প্রথমটি করতে পারে না।
ইলিটরিট

18
ব্যবহার করুন: [এক্সএমএলআরাই ("আইটেম"), এক্সএমএলআরআইটেম ("মাই ক্লাস", টাইপফ (মাই ক্লাস))]
আরভিডিকে

1
তার জন্য চিয়ার্স! প্রতিদিন কিছু শিখুন
অনাকাটা

2

সুস্পষ্ট সিরিয়ালাইজেশন ছাড়াই সিরিয়ালাইজিং ধরণের বিষয়ে সাবধান থাকুন, এর ফলে বিলম্ব হতে পারে et নেট সেগুলি তৈরি করে। আরএসএপিআরমিটারগুলি সিরিয়াল করার সময় আমি সম্প্রতি এটি আবিষ্কার করেছি


2

যদি আপনার এক্সএসডি বিকল্প গ্রুপগুলি ব্যবহার করে, তবে আপনি এটি স্বয়ংক্রিয়ভাবে সিরিয়ালাইজ করতে পারবেন না (ডি)। এই দৃশ্যটি পরিচালনা করতে আপনাকে নিজের সিরিয়ালাইজার লিখতে হবে।

যেমন।

<xs:complexType name="MessageType" abstract="true">
    <xs:attributeGroup ref="commonMessageAttributes"/>
</xs:complexType>

<xs:element name="Message" type="MessageType"/>

<xs:element name="Envelope">
    <xs:complexType mixed="false">
        <xs:complexContent mixed="false">
            <xs:element ref="Message" minOccurs="0" maxOccurs="unbounded"/>
        </xs:complexContent>
    </xs:complexType>
</xs:element>

<xs:element name="ExampleMessageA" substitutionGroup="Message">
    <xs:complexType mixed="false">
        <xs:complexContent mixed="false">
                <xs:attribute name="messageCode"/>
        </xs:complexContent>
    </xs:complexType>
</xs:element>

<xs:element name="ExampleMessageB" substitutionGroup="Message">
    <xs:complexType mixed="false">
        <xs:complexContent mixed="false">
                <xs:attribute name="messageCode"/>
        </xs:complexContent>
    </xs:complexType>
</xs:element>

এই উদাহরণে, একটি খামে বার্তাগুলি থাকতে পারে। যাইহোক, .NET- র ডিফল্ট সিরিয়ালটি ম্যাসেজ, উদাহরণম্যাসেজএ এবং উদাহরণমেসেজবি এর মধ্যে পার্থক্য করে না। এটি কেবল বেস বার্তা শ্রেণীর থেকে এবং থেকে সিরিয়ালাইজ হবে।


0

প্রাইভেট ভেরিয়েবল / বৈশিষ্ট্যগুলি এক্সএমএল সিরিয়ালাইজেশনে সিরিয়ালাইজড হয় না, তবে বাইনারি সিরিয়ালাইজেশন হয়।

আমি বিশ্বাস করি যে আপনি যদি জনসাধারণের সম্পত্তিগুলির মাধ্যমে ব্যক্তিগত সদস্যদের প্রকাশ করছেন - ব্যক্তিগত সদস্যরা সিরিয়ালযুক্ত হয় না তাই পাবলিক সদস্যরা সমস্ত নাল মান উল্লেখ করে।


এটি সত্য নয়। সরকারী সম্পত্তির সেটারকে ডাকা হত এবং সম্ভবত এটি ব্যক্তিগত সদস্যকে সেট করা হত।
জন স্যান্ডার্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.