2015-12-18 7 views
13

पर पैरामीटर पास करने के लिए कैसे करें Newtonsoft.Json के साथ किसी ऑब्जेक्ट को deserializing जब मुझे एक ठेकेदार को कुछ पैरेंट उदाहरण पास करने के साथ एक छोटी सी समस्या है।कन्स्ट्रक्टर deserializing जेसन

A a = new A() 
a.Bs = new List<B>() 
a.Bs.Add(new B(a)); 
a.Bs.Add(new B(a)); 
a.Bs.Add(new B(a)); 

var json = JsonConvert.SerializeObject(a); 

// Here i need to call the constructor of B when creating new instances 
var newA = JsonConvert.DeserializeObject<A>(json); 

समस्या है, कि जब वस्तु deserializing, null करेंगे:

मान लेते हैं मैं निम्नलिखित वर्गों

public class A 
{ 
    public string Str1 { get; set; } 

    public IList<B> Bs { get; set; } 
} 

public class B 
{ 
    public B(A a) 
    { 
     // a should not be null! 
     Console.WriteLine(a.Str) 
    } 
} 

और अब मैं serailze है और की तुलना में इस तरह वस्तु a deserialize चलो B के निर्माता को पास किया जाना चाहिए। क्या किसी ने इस मुद्दे/समस्या को हल किया है?

बहुत बहुत धन्यवाद!

+0

आप वास्तव में इस की जरूरत है, तो आप अपने डिजाइन में परिवर्तन कर सकते हैं। यदि आप क्रमबद्ध नहीं कर सकते हैं और फिर deserialize और ऑब्जेक्ट, आप serialization में इसका उपयोग नहीं करना चाहिए। – CodeCaster

+0

मुझे कोई त्रुटि संदेश नहीं मिला है, पास मूल्य केवल 'शून्य' है। आर्किटेक्चर को बदलना वास्तव में संभव नहीं है, क्योंकि इससे बहुत सारे रिफैक्टरिंग काम का कारण बन जाएगा। – BendEg

+0

मेरा मतलब है कि यदि आपकी कक्षा किसी आंतरिक सदस्य पर निर्भर करती है, तो आप इसे कम से कम deserialize नहीं कर सकते हैं। केवल सार्वजनिक सदस्यों पर डिफ़ॉल्ट कार्यों द्वारा serialization। आप एक सार्वजनिक बनाना चाहते हैं, या इसे किसी अन्य तरीके से क्रमबद्ध बनाना चाहते हैं। – CodeCaster

उत्तर

9

आपके प्रश्न और टिप्पणियों में आपने कहा है कि B में A के लिए कोई सार्वजनिक संपत्ति नहीं है। इसलिए, जब आप B को क्रमबद्ध करते हैं, तो JS0 पर कोई A लिखा नहीं जाएगा, क्योंकि Json.Net केवल डिफ़ॉल्ट रूप से सार्वजनिक जानकारी को क्रमबद्ध करता है। इसलिए, जब deserializing, B को फिर से बनाने के लिए पर्याप्त जानकारी नहीं होगी, क्योंकि JSON में A नहीं है। तो, चरण एक B का संदर्भ A पर जेसननेट के लिए दृश्यमान बना रहा है। यदि आप इसे सार्वजनिक नहीं करना चाहते हैं, तो यह ठीक है, लेकिन आपको कम से कम [JsonProperty] विशेषता के साथ सदस्य को चिह्नित करने की आवश्यकता होगी ताकि Json.Net को इसे "देखने" की अनुमति मिल सके।

public class B 
{ 
    [JsonProperty] 
    private A a; 

    public B(A a) 
    { 
     this.a = a; // be sure to set the A member in your constructor 
    } 
} 

अब अगर आप कर आप ऊपर एक दूसरी समस्या में पड़ जाएगा: अपने वर्ग संरचना एक संदर्भ लूप (AB रों जो प्रत्येक A से देख की एक सूची है), और serializer एक फेंक देंगे इस मामले में डिफ़ॉल्ट रूप से अपवाद। समाधान serializer की PreserveReferencesHandling सेटिंग Objects पर सेट करना है (डिफ़ॉल्ट None है)। यह धारावाहिक के दौरान संदर्भ लूप को संभालने की अनुमति नहीं देगा, बल्कि deserialization के दौरान मूल संदर्भों को भी संरक्षित करेगा, ताकि सभी B एस उसी A उदाहरण का संदर्भ लेंगे। (इस विशेष $id और $ref गुण है कि JSON में लिखा जाता है के माध्यम से पूरा किया है।)

JsonSerializerSettings settings = new JsonSerializerSettings 
{ 
    PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
}; 

var json = JsonConvert.SerializeObject(a, settings); 

var newA = JsonConvert.DeserializeObject<A>(json, settings); 

कार्य उदाहरण: https://dotnetfiddle.net/N0FUID

+0

से एक्सेस किया जाना चाहिए, जो मैं ढूंढ रहा था, पूरी तरह से काम करता है! आपका बहुत बहुत धन्यवाद! – BendEg

+0

कोई समस्या नहीं; मैं खुशी से मदद कर सकता है। –

संबंधित मुद्दे