স্ট্যাটিকালি পরিচিত নয় এমন ধরণের নির্দিষ্টকরণের জন্য এক্সএমআইএনক্লাইড বা সোপআইঙ্কেলবিউট অ্যাট্রিবিউট ব্যবহার করুন


99

নেট। এর সাথে কাজ করার সময় আমি একটি খুব অদ্ভুত সমস্যা পেয়েছি XmlSerializer

নিম্নলিখিত উদাহরণ ক্লাস গ্রহণ করুন:

public class Order 
{
    public PaymentCollection Payments { get; set; }

    //everything else is serializable (including other collections of non-abstract types)
}

public class PaymentCollection : Collection<Payment>
{
}

public abstract class Payment 
{
    //abstract methods
}

public class BankPayment : Payment
{
    //method implementations
}

আফাইক, InvalidOperationExceptionসিরিয়ালাইজারের উত্পন্ন প্রকারগুলি সম্পর্কে না জেনে এটি সমাধানের জন্য তিনটি ভিন্ন পদ্ধতি রয়েছে Payment

1. যোগ করার পদ্ধতি XmlIncludeথেকে Paymentবর্গ সংজ্ঞা:

সমস্ত ক্লাসকে বাইরের রেফারেন্স হিসাবে অন্তর্ভুক্ত করার কারণে এটি সম্ভব নয় যার উপর আমার কোনও নিয়ন্ত্রণ নেই।

2. XmlSerializerউদাহরণটি তৈরির সময় উত্পন্ন ধরণের প্রকারগুলি পাস করা

কাজ করে না।

৩. XmlAttributeOverridesসম্পত্তির ডিফল্ট সিরিয়ালাইজেশন ( এই এসও পোস্টে বর্ণিত হিসাবে ) ওভাররাইড করার জন্য লক্ষ্য সম্পত্তির জন্য সংজ্ঞা দেওয়া হচ্ছে

এছাড়াও কাজ করে না ( XmlAttributeOverridesসূচনাটি অনুসরণ করে)।

Type bankPayment = typeof(BankPayment);

XmlAttributes attributes = new XmlAttributes();
attributes.XmlElements.Add(new XmlElementAttribute(bankPayment.Name, bankPayment));

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Order), "Payments", attributes);

উপযুক্ত XmlSerializerকনস্ট্রাক্টর তখন ব্যবহার করা হবে।

দ্রষ্টব্য: দ্বারা কাজ করে না আমি বোঝাতে চাইছি InvalidOperationException( BankPaymentপ্রত্যাশিত ছিল না ... ) নিক্ষেপ করা হয়েছে

কেউ কি এই বিষয়ে কিছু আলোকপাত করতে পারেন? কেউ কীভাবে সমস্যাটি আরও ডিবাগ করবে?

উত্তর:


94

এটি আমার পক্ষে কাজ করেছে:

[XmlInclude(typeof(BankPayment))]
[Serializable]
public abstract class Payment { }    

[Serializable]
public class BankPayment : Payment {} 

[Serializable]
public class Payments : List<Payment>{}

XmlSerializer serializer = new XmlSerializer(typeof(Payments), new Type[]{typeof(Payment)});

16
সুতরাং বেস টাইপটি এর সমস্ত বাস্তবায়ন জানতে হবে? এটি খুব ভাল সমাধান বলে মনে হচ্ছে না। অন্য কোন উপায় আছে কি?
আলেকজান্ডার স্টলজ

4
এক্সএমএসআরশিরিজেবল অবজেক্ট তৈরি করার সময় জেনেরিক বাস্তবায়নের জন্য নতুন টাইপ পাস করার জন্য অ্যালেক্সান্ডারস্টলজ সবচেয়ে ভাল সমাধান। হিসাবে উল্লেখ করেছে stackoverflow.com/a/2689660/698127
Aamol

39

সবেমাত্র সমস্যা সমাধান করেছেন। আরও কিছুক্ষন খোঁড়াখুঁড়ি করার পরে, আমি এই এসও পোস্টটি পেয়েছি যা হুবহু একই অবস্থা জুড়ে। এটি আমাকে সঠিক পথে পেয়েছে।

মূলত, উত্পন্ন ক্লাসগুলি অতিরিক্ত ধরণের হিসাবে অন্তর্ভুক্ত করা হলেXmlSerializer ডিফল্ট নেমস্পেসটি জানা দরকার । এটি হওয়ার কারণটির সঠিক কারণ এখনও অজানা তবে এখনও সিরিয়ালাইজেশন কাজ করছে।


2

উপর বেজ এই আমি কন্সট্রাকটর পরিবর্তন করে এই সমস্যা সমাধানের পেরেছিলেন XmlSerializerপরিবর্তে ব্যবহার করছিলেন শ্রেণীর পরিবর্তন করি।

এই জাতীয় কিছু ব্যবহার না করে (অন্যান্য উত্তরে প্রস্তাবিত):

[XmlInclude(typeof(Derived))]
public class Base {}

public class Derived : Base {}

public void Serialize()
{
    TextWriter writer = new StreamWriter(SchedulePath);
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Derived>));
    xmlSerializer.Serialize(writer, data);
    writer.Close();
}

আমি এটা করেছি:

public class Base {}

public class Derived : Base {}

public void Serialize()
{
    TextWriter writer = new StreamWriter(SchedulePath);
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Derived>), new[] { typeof(Derived) });
    xmlSerializer.Serialize(writer, data);
    writer.Close();
}

2

কেবল বেসে এটি করুন, কোনও শিশুকে সিরিয়ালাইজ করা যায়, কম কোড ক্লিনার কোড।

public abstract class XmlBaseClass  
{
  public virtual string Serialize()
  {
    this.SerializeValidation();

    XmlSerializerNamespaces XmlNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
    XmlWriterSettings XmlSettings = new XmlWriterSettings
    {
      Indent = true,
      OmitXmlDeclaration = true
    };

    StringWriter StringWriter = new StringWriter();

    XmlSerializer Serializer = new XmlSerializer(this.GetType());
    XmlWriter XmlWriter = XmlWriter.Create(StringWriter, XmlSettings);
    Serializer.Serialize(XmlWriter, this, XmlNamespaces);
    StringWriter.Flush();
    StringWriter.Close();

    return StringWriter.ToString();

  }

  protected virtual void SerializeValidation() {}
}

[XmlRoot(ElementName = "MyRoot", Namespace = "MyNamespace")]
public class XmlChildClass : XmlBaseClass
{
  protected override void SerializeValidation()
  {
    //Add custom validation logic here or anything else you need to do
  }
}

এই পরিস্থিতিতে আপনি পরিস্থিতি বিবেচনা না করে শিশু শ্রেণিতে সিরিয়ালাইজ কল করতে পারেন এবং অবজেক্ট সিরিয়ালাইজ করার আগে আপনার যা করা দরকার তা করতে সক্ষম হতে পারেন।


2

আমি বিজলের সাথে একমত

[XmlInclude(typeof(ParentOfTheItem))]
[Serializable]
public abstract class WarningsType{ }

এছাড়াও যদি আপনাকে কোনও অন্তর্ভুক্ত আইটেমটিতে এই অন্তর্ভুক্ত শ্রেণীর প্রয়োগ করতে হয় তবে আপনি এটি করতে পারেন

[System.Xml.Serialization.XmlElementAttribute("Warnings", typeof(WarningsType))]
public object[] Items
{
    get
    {
        return this.itemsField;
    }
    set
    {
        this.itemsField = value;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.