জসন.ন. সিরিয়ালাইজ / উদ্ভূত প্রকারের deserialize?


99

json.net (নিউটনসফট)
আমি ডকুমেন্টেশনগুলি সন্ধান করছি তবে আমি এটি করতে বা এটি করার সর্বোত্তম উপায়টিতে কিছুই খুঁজে পাচ্ছি না।

public class Base
{
    public string Name;
}
public class Derived : Base
{
    public string Something;
}

JsonConvert.Deserialize<List<Base>>(text);

সিরিয়ালযুক্ত তালিকায় এখন আমার কাছে অবজেক্টস রয়েছে। আমি কীভাবে তালিকাটি ডিসরিয়ালাইজ করব এবং উত্পন্ন প্রকারগুলি ফিরে পাব?


উত্তরাধিকার কাজ করে না। আপনি জসনকনভার্টকে নির্দিষ্ট করতে পারেন ese ডেরিরিয়ালাইজ <বিপন্ন> (পাঠ্য); নাম ক্ষেত্র অন্তর্ভুক্ত। যেহেতু ডেরিভড আইএস এ বেস (চারপাশে অন্যভাবে নয়), বেস ডেরাইভের সংজ্ঞা সম্পর্কে কিছুই জানে না।
এমব্যাবকক

দুঃখিত, কিছুটা স্পষ্ট করে দিয়েছি। ইস্যুটি হ'ল আমার কাছে একটি তালিকা রয়েছে যা বেস এবং উত্পন্ন উভয় বস্তু ধারণ করে। সুতরাং আমি কীভাবে আমি নিউটসনফটকে বলি কীভাবে উদ্ভূত আইটেমগুলি ডিেসরিয়াল করতে হয় তা নির্ধারণ করা দরকার।
উইল

আমি এটা সমাধান করেছি। আমার একই সমস্যা আছে
লুইস কার্লোস চাভেরিয়া

উত্তর:


47

আপনি যদি আপনার টাইপটি সংরক্ষণ করেন text(যেমন আপনার এই দৃশ্যে হওয়া উচিত) তবে আপনি এটি ব্যবহার করতে পারেন JsonSerializerSettings

দেখুন: কীভাবে জেএসএনকে নিউটোনসফট জেএসওএন.এনইটি দিয়ে << বেস টাইপ> আইনিউমেবলের ডিেসিয়ালাইজ করা যায়

সাবধান, যদিও। ছাড়া আর কিছু ব্যবহার TypeNameHandling = TypeNameHandling.Noneনিজেকে খুলুন পারে একটি নিরাপত্তা দুর্বলতার


24
আপনি এটিও ব্যবহার করতে পারেন TypeNameHandling = TypeNameHandling.Auto- $typeএটি ঘোষণার ধরণ (যেমন Base) উদাহরণ টাইপের সাথে মেলে না এমন উদাহরণগুলির জন্য কেবল একটি সম্পত্তি যুক্ত করবে Derived। এইভাবে, এটি আপনার জাসনকে যতটা পুষে না TypeNameHandling.All
এজে রিচার্ডসন

আমি JSON '..., ...' এ নির্দিষ্ট ধরণের সমাধানের সময় ত্রুটি পেয়েছি। পথ '$ প্রকার', লাইন 1, অবস্থান 82. কোনও ধারণা?
briba

4
এটি সুরক্ষার সমস্যাগুলি উন্মুক্ত হওয়ার সাথে সাথে জনসাধারণের অবসরে
2017

4
@gjvdkamp JEEZ এর জন্য ধন্যবাদ, আমি এই সম্পর্কে জানতাম না। আমার পোস্টে যুক্ত করবে।
কামরানিকাস

98

আপনাকে টাইপ নেম হ্যান্ডলিং সক্ষম করতে হবে এবং সেটিংস প্যারামিটার হিসাবে (ডি) সিরিয়ালাইজারের কাছে দিতে হবে।

Base object1 = new Base() { Name = "Object1" };
Derived object2 = new Derived() { Something = "Some other thing" };
List<Base> inheritanceList = new List<Base>() { object1, object2 };

JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
string Serialized = JsonConvert.SerializeObject(inheritanceList, settings);
List<Base> deserializedList = JsonConvert.DeserializeObject<List<Base>>(Serialized, settings);

এর ফলে উত্পন্ন ক্লাসগুলির সঠিক deserialization হবে। এটির একটি অসুবিধা হ'ল এটি আপনার ব্যবহৃত সমস্ত অবজেক্টের নাম দেবে, যেমন এটি আপনার তালিকার নাম রাখবে যা আপনি অবজেক্টগুলিতে রাখছেন।


31
+1 আমি 30 মিনিটের জন্য গুগল করে যাচ্ছিলাম যতক্ষণ না আমি সত্যিই জানতে পারি যে আপনার সিরিয়ালাইজঅবজেক্ট এবং ডিসরিয়ালাইজ অবজেক্টের জন্য একই সেটিংস ব্যবহার করা দরকার। আমি ধরে নিয়েছি এটি নির্বিঘ্ন করার সময় সেখানে উপস্থিত থাকলে তা স্পষ্টভাবে ব্যবহার করবে, আমাকে বোকা বানাও।
এর্তি-ক্রিস ইলমা

24
TypeNameHandling.Autoএটিও করবে, এবং আরও ভাল কারণ এটি ক্ষেত্র / সম্পত্তির প্রকারের সাথে মেলে যখন উদাহরণের নামটি লিখেনি, যা বেশিরভাগ ক্ষেত্র / বৈশিষ্ট্যের ক্ষেত্রে প্রায়শই হয়।
রোমান স্টারকভ

4
অন্য সমাধান / প্রকল্পে যখন ডিসেরায়ালাইজেশন করা হয় তখন এটি কাজ করে না। সিরিয়ালাইজেশনে সমাধানের নামটি টাইপ হিসাবে এম্বেড করা হয়: "SOLUTIONNAME.Models.Model"। অন্য সমাধানে ডিসিরিয়ালাইজেশন করার সময় এটি "জসনসরিয়ালাইজেশন এক্সপেশন: এসেম্বলির 'SOLUTIONNAME' লোড করা
যায়নি

19

যেহেতু প্রশ্নটি এত জনপ্রিয়, আপনি যদি প্রকারের নাম এবং এর মান টাইপ করতে চান তবে কী করতে হবে তা যুক্ত করে নেওয়া দরকারী।

দীর্ঘতর উপায় হ'ল JsonConverterম্যানুয়ালি পরীক্ষা করে এবং প্রকারের বৈশিষ্ট্যটি সেট করে সিরিয়ালাইজেশন পরিচালনা করার জন্য কাস্টম গুলি লিখতে হয় ।

একটি সহজ উপায় হল জসনসুবটাইপগুলি ব্যবহার করা , যা সমস্ত বয়লারপ্লেট বৈশিষ্ট্যের মাধ্যমে পরিচালনা করে:

[JsonConverter(typeof(JsonSubtypes), "Sound")]
[JsonSubtypes.KnownSubType(typeof(Dog), "Bark")]
[JsonSubtypes.KnownSubType(typeof(Cat), "Meow")]
public class Animal
{
    public virtual string Sound { get; }
    public string Color { get; set; }
}

public class Dog : Animal
{
    public override string Sound { get; } = "Bark";
    public string Breed { get; set; }
}

public class Cat : Animal
{
    public override string Sound { get; } = "Meow";
    public bool Declawed { get; set; }
}

4
আমি প্রয়োজন পেতে, কিন্তু আমি বেস বর্গ সমস্ত "KnownSubType" s এর সচেতন করতে হচ্ছে একজন অনুরাগী ... নই
ম্যাট নোলেস

4
আপনি ডকুমেন্টেশন তাকান অন্য বিকল্প আছে। আমি কেবল আমার বেশি পছন্দ করি এমন উদাহরণ সরবরাহ করেছি।
rzippo

4
এটি নিরাপদ পদ্ধতি যা ডি-সিরিয়ালাইজেশনের মাধ্যমে স্বেচ্ছাসেবী প্রকারের লোড করতে আপনার পরিষেবাটি প্রকাশ করে না।
ডেভিড বার্গ

3

এই জসনকোনটিপ টাইপগুলি ব্যবহার করুন, এটি ব্যবহারের মতো এটি একইরকম উপায়, এটি কেবল জসনকে বৈষম্যমূলক করে:

[JsonConverter(typeof(JsonKnownTypeConverter<BaseClass>))]
[JsonKnownType(typeof(Base), "base")]
[JsonKnownType(typeof(Derived), "derived")]
public class Base
{
    public string Name;
}
public class Derived : Base
{
    public string Something;
}

এখন যখন আপনি ধারাবাহিকভাবে JSON বস্তুর যোগ করা হবে "$type"সঙ্গে "base"এবং "derived"মান এবং এটি deserialize জন্য ব্যবহারে হতে হবে

সিরিয়ালযুক্ত তালিকার উদাহরণ:

[
    {"Name":"some name", "$type":"base"},
    {"Name":"some name", "Something":"something", "$type":"derived"}
]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.