2009-06-24 20 views
8

का उपयोग कर इकाई फ्रेमवर्क ऑब्जेक्ट को सीरियलाइज़ करें I जावास्क्रिप्ट ऑब्जेक्ट (JSON) में इकाई फ्रेमवर्क ऑब्जेक्ट को क्रमबद्ध कैसे करें? मैंने JSON.NET का उपयोग करने का प्रयास किया लेकिन जब मैं इसे क्रमबद्ध करने का प्रयास करता हूं तो मुझे निम्न अपवाद मिल रहा है।Json.Net

अपवाद: Newtonsoft.Json.JsonSerializationException, संदेश = "स्व संदर्भित लूप"

हितेश

उत्तर

7

ऐसा लगता है यदि आप मूल DataContract serializer के रूप में ही सामान्य समस्या हो रही है की तरह चक्रीय संदर्भ के संबंध में। जबकि एक दूसरे का संदर्भ देने वाली वस्तुएं स्मृति में ऑब्जेक्ट ग्राफ़ के साथ काफी आम हैं, ऐसे चक्रवात संदर्भ अनिवार्य रूप से असीमित रिकर्सन में परिणाम देते हैं जब सीरियललाइज़र विशेष रूप से इसके लिए खाता नहीं लेता है। सामान्य गैर-बाइनरी धारावाहिक प्रारूपों (एक्सएमएल और जेएसओएन दो सबसे प्रचलित होने) में चक्रीय संदर्भों से निपटने के लिए कुछ मानक, स्थापित हैं।

माइक्रोसॉफ्ट ने .NET 3.5 में डेटाकंट्रैक सीरिएलाइज़र के लिए चक्रीय समस्या हल की एक्सएमएल में रेफ सेमेन्टिक्स का उपयोग करके एसपी 1। मेरे ज्ञान के लिए, JSON के लिए ऐसी कोई चीज़ नहीं है, जो कि JSON.NET आपको आपके ऑब्जेक्ट ग्राफ़ को क्रमबद्ध करने से रोक रहा है।

मैं यह सुनिश्चित करता हूं कि आपके ऑब्जेक्ट ग्राफ़ में केवल संदर्भ हैं जो दोनों तरीकों के बजाय नौसेना योग्य एक-तरफा हैं (यानी केवल माता-पिता से बच्चे, बच्चे से माता-पिता तक नहीं।) वे माता-पिता/बच्चे और बच्चे/माता-पिता चक्रीय संदर्भों के सबसे आम प्रकार हैं। यह भी हो सकता है कि निचले स्तर के बच्चे अंततः ग्राफ की जड़ का संदर्भ दे रहे हैं, जिससे अप्रत्यक्ष चक्रीय ग्राफ बनाया जा सकता है (हालांकि माता-पिता/बच्चे के लूप की तुलना में ये बहुत कम आम हैं।)

आप अपने ऑब्जेक्ट ग्राफ़ में किसी भी चक्रीय संदर्भ को खत्म करते हैं, तो आपको क्रमबद्ध करने में सक्षम होना चाहिए।

+0

धन्यवाद:

var context = new YourEntities(); context.Configuration.ProxyCreationEnabled = false; var results = context.YourEntity.Take(100).ToList(); 

फिर आप सुरक्षित रूप से JSON.NET धारावाहिक डेटा लौट सकते हैं इस प्रकार पाशन डिफ़ॉल्ट संदर्भ को छोड़ते हुए से। मैं ऑब्जेक्ट ग्राफ़ में किसी भी चक्रीय संदर्भ को खत्म नहीं करना चाहता था क्योंकि मुझे पूरा यकीन नहीं है कि यह कैसे करें और यह परिवर्तन करने के प्रभाव क्या होंगे। इसके बजाय मैंने सादे साधारण वस्तुओं को बनाया और एंटीटी फ्रेमवर्क ऑब्जेक्ट्स का उपयोग करके इन ऑब्जेक्ट्स को पॉप्युलेट किया और फिर सादे ऑब्जेक्ट्स को क्रमबद्ध किया और यह ठीक काम करता है। – Hitesh

+4

आम तौर पर, यह वास्तव में आपके डोमेन इकाइयों और आपके डीटीओ को एक दूसरे से स्वतंत्र रखने के लिए एक अच्छा अभ्यास है। अपने मूल, समृद्ध, ग्राफ राज्य में संस्थाएं व्यवसाय समस्या डोमेन को मॉडल करने और व्यावसायिक समस्याओं को हल करने का एक शानदार तरीका हैं, लेकिन वे सेवा-उन्मुखीकरण और क्रमबद्धता के लिए खुद को उधार नहीं देते हैं। मेरी निजी वरीयता है कि मेरे डोमेन को यथासंभव समृद्ध और पारस्परिक रूप से रखना है ताकि यह व्यवसाय को मॉडल कर सके और स्वतंत्र सेवा API प्रदान करे जो व्यक्तिगत क्रमिक डीटीओ प्रदान करे। – jrista

+0

यह समस्या द्वि-दिशात्मक नेविगेशन गुणों के कारण संदर्भों में केवल चक्रों से बड़ी है। आपके पास 10 ऑब्जेक्ट्स के बारे में क्या है जो सभी सटीक समान आश्रित वस्तु का संदर्भ देते हैं? 10 बार संदर्भित ऑब्जेक्ट को डुप्लिकेट किए बिना इस ग्राफ को क्रमबद्ध करने का मानक तरीका क्या है? और इस टोकन द्वारा क्लाइंट पक्ष पर डेटा को सही तरीके से deserializing, 10 अलग-अलग लोगों के बजाय संदर्भित वस्तु का एक उदाहरण दोबारा शुरू करना? JSON का उपयोग कर इसके लिए कोई मानक या सामान्य पैटर्न? – Marchy

4

मुझे यह समस्या थी और लूप के कारण संपत्ति में Newtonsoft.Json.JsonIgnoreAttribute जोड़कर हल किया गया। जाहिर है, उस संपत्ति को क्रमबद्ध नहीं किया जाएगा। इस समस्या से निपटने के लिए, मेरे पास आम तौर पर मेरी संस्थाओं में विदेशी संदर्भ आईडी और विदेशी वर्ग दोनों होंगे। मुझे एहसास है कि यह अंतर्ज्ञानी नहीं है (या सुपर महान ओओ), लेकिन जूलिया लर्मन द्वारा अपनी पुस्तक प्रोग्रामिंग एंटिटी फ्रेमवर्क: कोड फर्स्ट में अनुशंसित तरीका है। मैंने पाया है कि यह इकाई फ्रेमवर्क के साथ कई समस्याओं को सुगम बनाने में मदद करता है।

public class SomeEntity 
{ 
     [JsonIgnore] 
     public ForeignEntity SomeForeignEntity {get;set;} 
     public Guid ForeignEntityId {get;set;} 
} 

अद्यतन: मैं मैं भी तो जैसे DbContext पर प्रॉक्सी को निष्क्रिय करने के लिए आवश्यक उल्लेख करना भूल गया:

dataContext.Configuration.ProxyCreationEnabled = false; 

आप एक सेवा के लिए कोड (जो अगर तुम serializing कर रहे हैं संभावना लगती है) लिख रहे हैं, तो , तो शायद यह कोई समस्या नहीं है, लेकिन प्रॉक्सी निर्माण अक्षम होने पर कुछ चीजें खो जाती हैं। अधिक जानकारी के लिए यहां देखें: http://www.sellsbrothers.com/posts/Details/12665

मैं एमएस वेब एपीआई का उपयोग कर रहा है, तो मैं बस जब मैं अपने नियंत्रक का निर्माण प्रॉक्सी सृजन को निष्क्रिय:

public class MailingApiController : ApiController 
{ 
    public MailingApiController() 
    { 
     PreventDeepSerialization(); 
    } 

    private static void PreventDeepSerialization() 
    { 
     var dataContext = Injector.Get<IIntertwyneDbContext>(); 
     dataContext.Configuration.ProxyCreationEnabled = false; 
    } 
     .... 
1

इस के आसपास पाने के लिए मैं POCO आधारित संहिता सबसे पहले करने के लिए मेरे संस्थाओं बदल दिया। ऐसा करने के लिए अपनी एडीएमएक्स विंडो के अंदर राइट क्लिक करें और चुनें:

कोड जनरेशन आइटम> कोड टैब> ईएफ पॉको एंटीटी जेनरेटर जोड़ें।

ध्यान दें कि यदि आप इसे नहीं देखते हैं तो आपको इसे nuget के साथ स्थापित करने की आवश्यकता हो सकती है।

रनटाइम पर हालांकि ईएफ ट्रैकिंग उद्देश्यों के लिए उन ऑब्जेक्ट्स में प्रॉक्सी कक्षाएं जोड़ता है लेकिन वे क्रमबद्ध प्रक्रिया के साथ गड़बड़ करते हैं। इस हम बस गलत पर ProxyCreationEnabled सेट कर सकते हैं इस प्रकार रोकने के लिए: आपके उत्तर के लिए

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new jsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    });