JSON.Net स्व संदर्भित लूप का पता चला


111

मेरे पास 4 तालिकाओं के भीतर अपनी वेबसाइट के लिए एक mssql डेटाबेस है।

जब मैं इसका उपयोग करता हूं:

public static string GetAllEventsForJSON()
{
    using (CyberDBDataContext db = new CyberDBDataContext())
    {
        return JsonConvert.SerializeObject((from a in db.Events where a.Active select a).ToList(), new JavaScriptDateTimeConverter());
    }
}

निम्नलिखित त्रुटि में कोड परिणाम है:

Newtonsoft.Json.JsonSerializationException: सेल्फ रेफ़रिंग लूप '' DAL.CyberUser '' प्रकार के साथ संपत्ति 'CyberUser' के लिए पता लगाया। पथ '[0]। EventRegistrations [0] ।CyberUser.UserLogs [0]'।



क्या आप कृपया मेरे उत्तर को सही मानकर चिन्हित करेंगे? @ कोवु
मुहम्मद उमर एलशोरबागी

जवाबों:


212

मुझे अभिभावक / बाल संग्रहों के साथ बस यही समस्या थी और उस पोस्ट को मिला जिसने मेरे मामले को हल किया है। मैं केवल माता-पिता के संग्रह की वस्तुओं की सूची दिखाना चाहता था और उन्हें किसी भी बच्चे के डेटा की आवश्यकता नहीं थी, इसलिए मैंने निम्नलिखित का उपयोग किया और यह ठीक काम किया:

JsonConvert.SerializeObject(ResultGroups, Formatting.None,
                        new JsonSerializerSettings()
                        { 
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                        });

JSON.NET त्रुटि प्रकार के लिए खोजे गए सेल्फ रेफरेंसिंग लूप

यह Json.NET कोडप्लेक्स पृष्ठ पर भी संदर्भित है:

http://json.codeplex.com/discussions/272371

प्रलेखन: ReferenceLoopHandling सेटिंग


2
मामले के आधार पर आप PreserveReferencesHandling = PreserveReferencesHandling.Objects;यहां बताए अनुसार उपयोग कर सकते हैं: सॉल्व-सेल्फ-रेफरेंसिंग-लूप-इश्यू-व्हेन-यूजिंग-न्यूटनसॉफ्ट-जसन
दिमित्री ट्रॉन्को 13

वेबएपीआई OData v4 में, मैंने पाया है कि डेटा के कुछ प्रकार के दोनों ReferenceLoopHandling.Ignore और PreserveReferencesHandling.Objects आवश्यक
क्रिस स्कालर

1
अल्लेलुआह गाते हैं, इसलिए केवल 1 से वोटिंग ही पर्याप्त नहीं है
जेपी चपलेउ

42

लूप संदर्भों को अनदेखा करना और उन्हें क्रमबद्ध नहीं करना है। में यह व्यवहार निर्दिष्ट है JsonSerializerSettings

JsonConvertएक अधिभार के साथ एकल :

JsonConvert.SerializeObject((from a in db.Events where a.Active select a).ToList(), Formatting.Indented,
    new JsonSerializerSettings() {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    }
);

यदि आप इसे डिफ़ॉल्ट व्यवहार बनाना चाहते हैं, तो Global.asax.cs में कोड के साथ एक ग्लोबल सेटिंग जोड़ें Application_Start():

JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
     Formatting = Newtonsoft.Json.Formatting.Indented,
     ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
};

संदर्भ: https://github.com/JamesNK/Newtonsoft.Json/issues/78


3
इस के साथ सीरियल करने में मेरे लिए बहुत लंबा समय लगता है
डेनियल

यह तब काम नहीं करता है जब परिपत्र लूप वाली वस्तु NHibernate मॉडल POCOs होती है (उस स्थिति में क्रमांकन एक टन कचरा प्राप्त करता है, या कभी-कभी बस बाहर निकलता है)।
फर्नांडो गोंजालेज सांचेज़

"IsSecuritySafeCritical": false, "IsSecurityTransparent": false, "MethodHandle": {"value": {"value": 140716810003120}}, "Atteses": 150, "CallingConference": 1, "ReturnType": "System.Void" , System.PStreet.CoreLib, संस्करण = 4.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = 7cec85d7bea7798e "," ReturnTypeCustomAttributes ": {" ParameterPype ":" System.Void, System.PStreet.CoreLib, संस्करण = 4.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = 7cec85d7bea7798e "," Name ": null," HasDefaultValue ": true," DefaultValue ": null," RawDefaultValue ": null," MetadataToken ": 134217728," Attributes "" 0 " "ISIN": झूठे, "IsLcid": झूठी ,. ... आदि।

37

यदि ASP.NET Core MVC का उपयोग किया जाता है, तो इसे अपने स्टार्टअप की कॉन्फ़िगर विधि सेवा में जोड़ें। फ़ाइल:

services.AddMvc()
    .AddJsonOptions(
        options => options.SerializerSettings.ReferenceLoopHandling =            
        Newtonsoft.Json.ReferenceLoopHandling.Ignore
    );

2
मैंने पुष्टि की है कि यह समाधान WebAPI EntityFramework Core 2.0 के साथ भी काम करता है
cesar-moya

13

यह आपकी मदद कर सकता है।

public MyContext() : base("name=MyContext") 
{ 
    Database.SetInitializer(new MyContextDataInitializer()); 
    this.Configuration.LazyLoadingEnabled = false; 
    this.Configuration.ProxyCreationEnabled = false; 
} 

http://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7


4
यदि आप भी एसिंक्स विधियों का उपयोग कर रहे हैं तो यह सबसे अच्छा तरीका है। यह एक वास्तविक दर्द हो सकता है, लेकिन यह बहुत सारे मुद्दों को हल करता है जो आपके पास अन्यथा (इस एक सहित) होगा और यह भी अधिक प्रदर्शन कर सकता है क्योंकि आप केवल क्वेरी कर रहे हैं जो आप उपयोग करेंगे।
जोश मैककिरिन

अपने xyz.edmx में, xyz.Context.vb फ़ाइल खोलें जो डिफ़ॉल्ट रूप से छिपी होगी। इसमें codePublic Sub New () Mybase.New ("name = EntityConName") एंड सब होगा code। अब End Sub से पहले codeMe.Configuration.LazyLoadingEnabled = False Me.Configuration.ProxyCreationEnabled = False जोड़ें जो वेबएपी code से आपके जंक आउटपुट में 'सेल्फ रेफरेंसिंग लूप' की त्रुटि से छुटकारा दिलाएगा।
वेंकट

मैंने पाया कि यह मेरे लिए काम नहीं किया। मैंने AsNoTracking () का उपयोग किया और इसे ठीक किया। शायद किसी और की मदद करें
scottsanpedro

अगर हम आपका कोड देख सकते हैं तो @scotanpedroro बेहतर था।
ddagsan

6

आपको ऑब्जेक्ट रेफरेंस प्रिजर्व करना होगा:

var jsonSerializerSettings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects
};

फिर अपनी क्वेरी की var q = (from a in db.Events where a.Active select a).ToList();तरह कॉल करें

string jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(q, jsonSerializerSettings);

देखें: https://www.newtonsoft.com/json/help/html/PreserveObjectReferences.htm


4

अपने मॉडल वर्ग में "[JsonIgnore]" जोड़ें

{
  public Customer()
  {
    Orders = new Collection<Order>();
  }

public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }

[JsonIgnore]
public ICollection<Order> Orders { get; set; }
}

3

मैं डॉट.नेट कोर 3.1 का उपयोग कर रहा हूं और इसकी खोज की है

"Newtonsoft.Json.JsonSerializationException: आत्म संदर्भित लूप संपत्ति के लिए पता चला"

मैं इसे इस सवाल से जोड़ रहा हूं, क्योंकि यह एक आसान संदर्भ होगा। आपको Start..cs फ़ाइल में निम्न का उपयोग करना चाहिए:

 services.AddControllers()
                .AddNewtonsoftJson(options =>
                {
                    // Use the default property (Pascal) casing
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                });

2

asp.net कोर 3.1.3 के लिए यह मेरे लिए काम किया

services.AddControllers().AddNewtonsoftJson(opt=>{
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });

1

JsonConvert.SerializeObject(ObjectName, new JsonSerializerSettings(){ PreserveReferencesHandling = PreserveReferencesHandling.Objects, Formatting = Formatting.Indented });


6
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन यह कोड इस और क्यों या कैसे का उत्तर देता है, इस संबंध में अतिरिक्त संदर्भ प्रदान करता है।
एलेक्स रिआबोव

1

कभी-कभी आपके पास लूप्स होते हैं आपके प्रकार के वर्ग में अन्य वर्गों के संदर्भ होते हैं और उन कक्षाओं में आपके प्रकार वर्ग के संदर्भ होते हैं, इस प्रकार आपको उन मापदंडों का चयन करना होगा जिनकी आपको इस कोड की तरह, जौन स्ट्रिंग में बिल्कुल आवश्यकता है।

List<ROficina> oficinas = new List<ROficina>();
oficinas = /*list content*/;
var x = JsonConvert.SerializeObject(oficinas.Select(o => new
            {
                o.IdOficina,
                o.Nombre
            }));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.