JSON.NET ত্রুটি স্বতঃপ্রকাশের লুপ টাইপের জন্য সনাক্ত হয়েছে


494

আমি পোকো ক্লাসটি সিরিয়ালাইজ করার চেষ্টা করেছি যা সত্তা ডেটা মডেল .edmx থেকে স্বয়ংক্রিয়ভাবে উত্পন্ন হয়েছিল এবং যখন আমি ব্যবহার করেছি

JsonConvert.SerializeObject 

আমি নিম্নলিখিত ত্রুটি পেয়েছি:

System.data.entity টাইপের জন্য স্ব-উল্লেখের লুপটি ত্রুটিযুক্ত।

আমি কীভাবে এই সমস্যার সমাধান করব?



: আপনি যখন Linq এবং MVC ব্যবহার করছেন stackoverflow.com/a/38241856
aDDin

.NET কোর 2 ব্যবহার করার সময়: stackoverflow.com/a/48709134/4496145
ডেভ স্কেন্ডার

2
এই ত্রুটিটি আমার কাছে ঘটেছিল, যখন আমি কোনও asyncপদ্ধতি কল (ক Task) এর ফলাফলটি সিরিয়াল করতে চেয়েছিলাম এবং awaitবিবৃতি উপসর্গ ভুলে গিয়েছিলাম ।
উয়ে কেইম

উত্তর:


485

এটিই ছিল সেরা সমাধান https://code.msdn.microsoft.com/Loop-References-handling-in-caaffaf7

1 স্থির করুন: বিশ্বব্যাপী বিজ্ঞপ্তি রেফারেন্স উপেক্ষা

(আমি এটিকে আরও বেছে নিয়েছি / বেছে নিয়েছি)

Json.net সিরিয়ালের সাথে বিজ্ঞপ্তি সংক্রান্ত রেফারেন্স উপেক্ষা করার বিকল্প রয়েছে। নিম্নলিখিত কোডটি WebApiConfig.csফাইলটিতে রাখুন :

 config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling 
= Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

সাধারণ ফিক্সটি রেফারেন্সটিকে উপেক্ষা করতে সিরিয়ালাইজারকে তৈরি করবে যা লুপের কারণ হবে। তবে এর সীমাবদ্ধতা রয়েছে:

  • লুপিং রেফারেন্স তথ্যটি ডেটা হারায়
  • এই ফিক্সটি কেবল JSON.net এ প্রযোজ্য
  • গভীর রেফারেন্স চেইন থাকলে রেফারেন্সের স্তরটি নিয়ন্ত্রণ করা যায় না

আপনি যদি কোনও অপ-এপি এসপিএন নেট প্রকল্পে এই ফিক্সটি ব্যবহার করতে চান তবে উপরের লাইনটি এতে যুক্ত করতে পারেন Global.asax.csতবে প্রথমে যুক্ত করুন:

var config = GlobalConfiguration.Configuration;

আপনি যদি নেট কোর প্রকল্পে এটি ব্যবহার করতে চান তবে আপনি এই Startup.csহিসাবে পরিবর্তন করতে পারেন :

  var mvc = services.AddMvc(options =>
        {
           ...
        })
        .AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

সমাধান 2: বিশ্বব্যাপী বিজ্ঞপ্তি রেফারেন্স সংরক্ষণ করা ving

এই দ্বিতীয় ফিক্সটি প্রথমটির মতো। কেবল কোডটি এতে পরিবর্তন করুন:

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling 
     = Newtonsoft.Json.ReferenceLoopHandling.Serialize;     
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling 
     = Newtonsoft.Json.PreserveReferencesHandling.Objects;

এই সেটিংটি প্রয়োগের পরে ডেটা আকার পরিবর্তন করা হবে।

[
   {
      "$id":"1",
      "Category":{
         "$id":"2",
         "Products":[
            {
               "$id":"3",
               "Category":{
                  "$ref":"2"
               },
               "Id":2,
               "Name":"Yogurt"
            },
            {
               "$ref":"1"
            }
         ],
         "Id":1,
         "Name":"Diary"
      },
      "Id":1,
      "Name":"Whole Milk"
   },
   {
      "$ref":"3"
   }
]

$ আইডি এবং $ রেফ সমস্ত রেফারেন্স রাখে এবং অবজেক্টের গ্রাফ স্তরকে সমতল করে তোলে, তবে ক্লায়েন্ট কোডটি ডেটা গ্রহণের জন্য আকারের পরিবর্তনটি জানতে হবে এবং এটি কেবল JSON.NET সিরিয়ালাইজারের ক্ষেত্রেও প্রযোজ্য।

ফিক্স 3: উপেক্ষা করুন এবং রেফারেন্স গুণাবলী সংরক্ষণ করুন

এই ফিক্সটি মডেল বা সম্পত্তি স্তরের সিরিয়ালাইজেশন আচরণটি নিয়ন্ত্রণ করতে মডেল শ্রেণিতে বৈশিষ্ট্যগুলি সজ্জিত করে। সম্পত্তি উপেক্ষা করার জন্য:

 public class Category 
    { 
        public int Id { get; set; } 
        public string Name { get; set; } 

        [JsonIgnore] 
        [IgnoreDataMember] 
        public virtual ICollection<Product> Products { get; set; } 
    } 

জসনআইগনোর জেএসএন.এনইটি এবং ইগনোরডেটা মেম্বার এক্সএমএলডিসিএসিয়ালাইজারের জন্য। রেফারেন্স সংরক্ষণ করতে:

 // Fix 3 
        [JsonObject(IsReference = true)] 
        public class Category 
        { 
            public int Id { get; set; } 
            public string Name { get; set; } 

           // Fix 3 
           //[JsonIgnore] 
           //[IgnoreDataMember] 
           public virtual ICollection<Product> Products { get; set; } 
       } 

       [DataContract(IsReference = true)] 
       public class Product 
       { 
           [Key] 
           public int Id { get; set; } 

           [DataMember] 
           public string Name { get; set; } 

           [DataMember] 
           public virtual Category Category { get; set; } 
       }

JsonObject(IsReference = true)]JSON.NET এর জন্য এবং [DataContract(IsReference = true)]এক্সএমএলডিসিএসিয়ালাইজারের জন্য। দ্রষ্টব্য: DataContractক্লাসে আবেদনের পরে , আপনাকে DataMemberএমন বৈশিষ্ট্যগুলি যুক্ত করতে হবে যা আপনি সিরিয়াল করতে চান।

বৈশিষ্ট্যগুলি জসন এবং এক্সএমএল সিরিয়াল উভয় ক্ষেত্রে প্রয়োগ করা যেতে পারে এবং মডেল শ্রেণিতে আরও নিয়ন্ত্রণ দেয়।


7
ফিক্স 3 আমার জন্য কাজ করা হয়। কেবলমাত্র ডেটা কন্ট্রাক্ট এবং ডেটা মেম্বার বৈশিষ্ট্যগুলি মুছে ফেলুন এবং ডিটিওগুলিতে জসনঅবজেক্ট (ইসরেফারেন্স = সত্য) রাখুন। এবং এটি কাজ করে। ধন্যবাদ।
মাস্টার

1
এই এক গ্লোবাল কনফিগারেশন চেষ্টা করুন। কনফিগারেশন
বিশ্ব হানা

1
ফিক্স 3 এর সুবিধা রয়েছে যে এটি ক্লায়েন্ট কোডে কাজ করে যেখানে কোনও
গ্লোবাল কনফিগারেশন

1
@ বিশয়হান্না, আপনি কি আপনার উত্তরটি এএসপি.এনইটি অ্যাপ্লিকেশন থেকে এটি ব্যবহার করার অনুমতি দেওয়ার জন্য সম্পাদনা করতে পারেন? আপনি আমার প্রস্তাবিত সম্পাদনাটি ব্যবহার করতে পারেন: stackoverflow.com/review/suggested-edits/17797683
NH।

2
ব্যবহার [JsonIgnore]অ্যাট্রিবিউট আমার জন্য কাজ উপরে।
নাথান বেক

467

জসনসারিয়ালাইজারসেটিংস ব্যবহার করুন

  • ReferenceLoopHandling.Error(ডিফল্ট) ত্রুটি করবে যদি কোনও রেফারেন্স লুপের মুখোমুখি হয়। এ কারণেই আপনি ব্যতিক্রম পান।
  • ReferenceLoopHandling.Serialize যদি অবজেক্টগুলি নেস্টেড হয় তবে অনির্দিষ্টকালের জন্য কার্যকর না হয়।
  • ReferenceLoopHandling.Ignore যদি কোনও বস্তু এটির নিজেরাই চাইল্ড অবজেক্ট হয় তবে এটি সিরিয়ালিয়াল করবে না।

উদাহরণ:

JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented, 
new JsonSerializerSettings { 
        ReferenceLoopHandling = ReferenceLoopHandling.Serialize
});

আপনি একটি বস্তু অনির্দিষ্টকালের জন্য আপনি ব্যবহার করতে পারেন নেস্টেড হয় ধারাবাহিকভাবে করতে হবে PreserveObjectReferences একটি StackOverflowException এড়ানো।

উদাহরণ:

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

আপনি যে সিরিজটি সিরিয়াল করছেন সেটি কী কী তা চয়ন করুন P

রেফারেন্স http://james.newtonking.com/json/help/


66
একটি ডেটাটেবল সিরিয়াল করার সময় আমি ত্রুটির মুখোমুখি হয়েছি। আমি ReferenceLoopHandling = ReferenceLoopHandling.Ignoreএটির কাজ করার জন্য ব্যবহার করেছি

8
যদি ডেটাতে রেফারেন্স লুপ থাকে তবে ReferenceLoopHandling.Serializeসিরিয়ালাইজারটি একটি অসীম পুনরাবৃত্ত লুপে প্রবেশ করবে এবং স্ট্যাকটিকে উপচে ফেলবে।
ব্রায়ান রজার্স

1
সঠিক। প্রশ্নটি একটি ইএফ মডেল সম্পর্কে হিসাবে একটি বৈধ উদ্বেগ। সমস্ত উপলব্ধ বিকল্প দিতে সংশোধিত।
ডালসফট

1
কোনও বস্তুকে সিরিয়ালাইজ করার চেষ্টা করার সময় আমি এই একই ত্রুটির মুখোমুখি হয়েছি ... তবে এনাম টাইপ ব্যতীত অন্য কোনও রেফারেন্স নেই ...
মেরিন

1
আমার জন্য ইএফই এই সমস্যার মূল কারণ কারণ স্ব-রেফারেন্সযুক্ত সত্তা পুরো জায়গা জুড়ে।
তেওমান শিপাহী

57

ফিক্সটি হ'ল লুপ রেফারেন্সগুলি উপেক্ষা করা এবং সেগুলি ক্রিয়াকলাপ না করা। এই আচরণটি নির্দিষ্ট করা আছে JsonSerializerSettings

JsonConvertএকটি ওভারলোডের সাথে একক :

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

Application_Start()Global.asax.cs এ কোড সহ গ্লোবাল সেটিং :

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

তথ্যসূত্র: https://github.com/JamesNK/Newtonsoft.Json/issues/78


আপনি যখন বিশ্বব্যাপী সেটিংস করেন তখন কেন আপনি বিন্যাসটি ইন্ডেন্ট করাতে সেট করেন?
মারফিব্রো 2

এই সমস্যাটি সমাধান করার জন্য অবশ্যই আমাদের কী প্রয়োজন (একটি স্থাপনার সময় আবিষ্কার করা হয়েছিল)! আপনি দা মানুষ .... আমাদের সময় বাঁচানোর জন্য ধন্যবাদ !!
রায়ান ইস্টব্রুক

আমি "জসনকনভার্ট.ডাফল্টসেটেটিংস" = () => নতুন জসনসিরিয়ালাইজারসেটেটিং {....} ক্লাসে "স্টার্টআপ.স"
বেলদি আনোয়ার

45

এটি করার সহজতম উপায় হ'ল নুগেট থেকে জসন.এনইটি ইনস্টল করা [JsonIgnore]এবং শ্রেণীর ভার্চুয়াল সম্পত্তির বৈশিষ্ট্য যুক্ত করুন , উদাহরণস্বরূপ:

    public string Name { get; set; }
    public string Description { get; set; }
    public Nullable<int> Project_ID { get; set; }

    [JsonIgnore]
    public virtual Project Project { get; set; }

যদিও এই দিনগুলিতে, আমি কেবলমাত্র সেই সমস্ত বৈশিষ্ট্য দিয়ে একটি মডেল তৈরি করেছি যাতে এটি হালকা হয়, এটি অযাচিত সংগ্রহগুলি অন্তর্ভুক্ত করে না, এবং উত্পন্ন ফাইলগুলি পুনর্নির্মাণ করার সময় আমি আমার পরিবর্তনগুলি হারাতে পারি না ...


3
নিউটন জেএসওএন ব্যবহার করে সেরা উত্তর
আইজেন

21

.NET কোর 1.0 এ, আপনি এটি আপনার স্টার্টআপ। সি ফাইলগুলিতে বিশ্বব্যাপী সেটিংস হিসাবে সেট করতে পারেন:

using System.Buffers;
using Microsoft.AspNetCore.Mvc.Formatters;
using Newtonsoft.Json;

// beginning of Startup class

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options =>
        {
            options.OutputFormatters.Clear();
            options.OutputFormatters.Add(new JsonOutputFormatter(new JsonSerializerSettings(){
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
            }, ArrayPool<char>.Shared));
        });
    }

তবে এই ক্ষেত্রে, যদি আমি সচেতন হতে চাই যে এই সম্পত্তিটি উপেক্ষা করা হয় আমি তখন কোনও ব্যতিক্রম পাব না।
মেয়ার স্পিজিটর

10

আপনি যদি .NET কোর 2.x ব্যবহার করছেন তবে আপনার কনফিগার সার্ভিস বিভাগটি স্টার্টআপ। সিগুলিতে আপডেট করুন

https://docs.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization

    public void ConfigureServices(IServiceCollection services)
    {
    ...

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

    ...
    }

আপনি যদি এমভিসি ছাড়াই .NET কোর 3.x ব্যবহার করে থাকেন তবে এটি হবে:

services.AddControllers()
  .AddNewtonsoftJson(options =>
      options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
   );

আপনি যদি সত্ত্বা ফ্রেমওয়ার্ক এবং ডাটাবেস-প্রথম ডিজাইনের প্যাটার্নটি ব্যবহার করেন তবে এই রেফারেন্স লুপ হ্যান্ডলিং প্রায় বাধ্যতামূলক।


2
আমি যদি ব্যবহার না করি services.AddMvc()?
prisar

2
এটা কি খারাপ অভ্যাস?
রেনান কোয়েলহো

প্রথম নজরে আপনি মনে করতে পারেন যে এটি একটি খারাপ অনুশীলন কারণ এটি পুরানো "অসীম লুপ" সমস্যা এড়ানো "ইচ্ছাকৃত নকশা" কে ওভাররাইড করতে পারে। তবে, আপনি যদি ক্লাসগুলির জন্য আপনার ব্যবহারের কেসগুলি সম্পর্কে ভাবেন তবে আপনার একে অপরের সাথে রেফার করার প্রয়োজন হতে পারে। উদাহরণস্বরূপ, আপনি গাছ> ফল এবং ফল> ফল উভয় অ্যাক্সেস করতে চাইতে পারেন।
ডেভ স্কেন্ডার

এছাড়াও, আপনি যদি আপনার ডাটাবেসে আপনার বিদেশী কী কীভাবে সেটআপ করেন তার উপর নির্ভর করে আপনি যদি সত্ত্বা ফ্রেমওয়ার্কের মতো কোনও ডেটাবেস-প্রথম ডিজাইন প্যাটার্ন ব্যবহার করেন তবে এটি স্বয়ংক্রিয়ভাবে এই চক্রীয় রেফারেন্স তৈরি করবে, তাই আপনি যদি এই সেটিংটি ব্যবহার করতে চান তবে আপনাকে 'রিভার্স ইঞ্জিনিয়ারিং আপনার ক্লাস।
ডেভ স্কেন্ডার

9

আপনার লুপ ইস্যু যখন হয় তখন নিউটোনসফটজসনকে সিরিয়ালাইজ করতে, আমার ক্ষেত্রে আমার গ্লোবাল.অ্যাসাক্স বা এপিকনফিগ পরিবর্তন করার দরকার নেই। আমি কেবল লুপিং হ্যান্ডলিং উপেক্ষা করে জসনসিরিয়েলাইজসেটিং ব্যবহার করি।

JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var lst = db.shCards.Where(m => m.CardID == id).ToList();
string json = JsonConvert.SerializeObject(lst, jss);

1
যদি অন্য কেউ যদি ওয়াচ উইন্ডোতে যাওয়ার জন্য একটি লাইনারের জন্য এখানে আসে তবে এটি পাঠ্যটি অনুসন্ধানযোগ্য:Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize, new Newtonsoft.Json.JsonSerializerSettings() {ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore});
গ্রাহাম

8

স্ব-রেফারেন্সিং লুপটি অক্ষম করতে আমরা এই দুটি লাইন DbContext শ্রেণীর নির্মাত্রে যুক্ত করতে পারি

public TestContext()
        : base("name=TestContext")
{
    this.Configuration.LazyLoadingEnabled = false;
    this.Configuration.ProxyCreationEnabled = false;
}

এটি সর্বাধিক সহজ একটি এবং কবজির মতো কাজ করা । ভোট দিয়েছেন, অনেক অনেক ধন্যবাদ ...
মুরাত ইল্ডেজ

যেমনটি আমি অন্য প্রশ্নে লিখেছি: আমি এই ধরণের উত্তর পছন্দ করি না কারণ আপনি EF6 এর একটি বৈশিষ্ট্যটি বন্ধ করছেন যা ডিফল্টরূপে সক্ষম হয় এবং এই কোডের এই অংশটি প্রোগ্রামের অন্যান্য অংশগুলিকে ভেঙে দিতে পারে। এটি কী করে এবং কী ধরণের প্রতিক্রিয়া রয়েছে তা আপনার ব্যাখ্যা করা উচিত।
এল ম্যাক

@ এলম্যাক আপনি ঠিক বলেছেন, তবে আমাদের যদি সেই বৈশিষ্ট্যটির প্রয়োজন না হয় তবে কেন এই সমাধানটি ব্যবহার করতে পারবেন না?
সঞ্জয় নিশাদ

@ সঞ্জয়নিশাদ আপনার যদি বৈশিষ্ট্যটির প্রয়োজন না হয় তবে আমি কিছু মনে করি না। এটি কেবলমাত্র ব্যবহারকারীদের সম্পর্কে যা তারা জানেন না যে তারা কী অক্ষম করছে।
এল ম্যাক

6

আপনি সম্পত্তিটিতেও একটি বৈশিষ্ট্য প্রয়োগ করতে পারেন। [JsonProperty( ReferenceLoopHandling = ... )]অ্যাট্রিবিউট ভাল এই উপযুক্ত।

উদাহরণ স্বরূপ:

/// <summary>
/// Represents the exception information of an event
/// </summary>
public class ExceptionInfo
{
    // ...code omitted for brevity...

    /// <summary>
    /// An inner (nested) error.
    /// </summary>
    [JsonProperty( ReferenceLoopHandling = ReferenceLoopHandling.Ignore, IsReference = true )]
    public ExceptionInfo Inner { get; set; }

    // ...code omitted for brevity...    
}

আশা করি যে সাহায্য করবে, জানস


4

লুপ রেফারেন্সগুলি উপেক্ষা করার জন্য এবং এমভিসি 6 এ তাদের বিশ্বব্যাপী ক্রমিকায়িত না করার জন্য স্টার্টআপ.এস-এ নিম্নলিখিত ব্যবহার করুন:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().Configure<MvcOptions>(options =>
        {
            options.OutputFormatters.RemoveTypesOf<JsonOutputFormatter>();
            var jsonOutputFormatter = new JsonOutputFormatter();
            jsonOutputFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            options.OutputFormatters.Insert(0, jsonOutputFormatter);
        });
    }

2

এটি WebApiConfig.csক্লাসে ব্যবহার করুন :

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

2

আমার জন্য আমাকে অন্য পথে যেতে হয়েছিল। JSON.Net সিরিয়ালাইজারটি ঠিক করার চেষ্টা করার পরিবর্তে আমাকে আমার ডেটাঅন্টেক্সটে অলস লোডিংয়ের পরে যেতে হয়েছিল।

আমি এটি কেবলমাত্র আমার বেস ভাণ্ডারে যুক্ত করেছি:

context.Configuration.ProxyCreationEnabled = false;

"কনটেক্সট" অবজেক্টটি কনস্ট্রাক্টর প্যারামিটার যা আমি আমার বেস রিপোসিটরিতে ব্যবহার করি কারণ আমি নির্ভরতা ইনজেকশন ব্যবহার করি। এর পরিবর্তে আপনি যে কোনও জায়গায় প্রক্সিক্রিয়েশনএএনবেলড সম্পত্তিটি ইনস্ট্যান্ট করতে পারেন।

http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html


2

আমার এই ব্যতিক্রম ছিল এবং আমার কাজের সমাধানটি সহজ এবং সহজ,

এতে জসনআইগোর বৈশিষ্ট্য যুক্ত করে রেফারেন্স করা সম্পত্তিটিকে উপেক্ষা করুন:

[JsonIgnore]
public MyClass currentClass { get; set; }

সম্পত্তিটি যখন আপনি ডিজিট্রাইজ করেন তখন পুনরায় সেট করুন:

Source = JsonConvert.DeserializeObject<MyObject>(JsonTxt);
foreach (var item in Source)
        {
            Source.MyClass = item;
        }

নিউটনসফট.জসন ব্যবহার করে;


এটি আমার প্রয়োজন ম্যাজিক। এটি সমাধান করুন[JsonIgnore]
saviour123

2

টীম:

এটি এএসপি.এনইটি কোর সাথে কাজ করে; উপরের চ্যালেঞ্জটি হ'ল আপনি কীভাবে 'উপেক্ষা করার সেটিংস সেট' করেছেন। আপনি কীভাবে আপনার অ্যাপ্লিকেশন সেটআপ করবেন তার উপর নির্ভর করে এটি বেশ চ্যালেঞ্জিং হতে পারে। আমার জন্য যা কাজ করেছে তা এখানে।

এটি আপনার সার্বজনীন শূন্য কনফিগার সার্ভিসেস (আইএসভারসোলেকশন পরিষেবা) বিভাগে স্থাপন করা যেতে পারে।

services.AddMvc().AddJsonOptions(opt => 
        { 
      opt.SerializerSettings.ReferenceLoopHandling =
      Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });

2

লোকেরা ইতিমধ্যে শ্রেণিতে ভার্চুয়াল সম্পত্তিতে [জসনআইগনোর] যুক্ত হওয়ার বিষয়ে কথা বলেছে, উদাহরণস্বরূপ:

[JsonIgnore]
public virtual Project Project { get; set; }

আমি অন্য অপশনটিও ভাগ করব, [জসনপ্রপার্টি (নালভ্যালিউহ্যান্ডলিং = নুলভ্যালুহ্যান্ডলিং Iআনগোর)] যা সম্পত্তিটি কেবল সিরিয়ালাইজেশন থেকে বাদ দিলে কেবলমাত্র:

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public virtual Project Project { get; set; }

1

.NET কোর 3.0 এর জন্য, নীচে প্রদর্শিত হিসাবে স্টার্টআপ.সি ক্লাস আপডেট করুন।

public void ConfigureServices(IServiceCollection services)
{
...

services.AddControllers()
    .AddNewtonsoftJson(
        options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    );

...
}

দেখুন: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-5/


0

কেবল Configuration.ProxyCreationEnabled = false;প্রসঙ্গ ফাইলের ভিতরে রাখুন; এটি সমস্যার সমাধান করবে।

public demEntities()
    : base("name=demEntities")
{
    Configuration.ProxyCreationEnabled = false;
}

0

কাস্টম কনফিগারেশনের সাথে আমার সমস্যা সমাধান হয়েছে

services.AddMvc(
  // ...
               ).AddJsonOptions(opt =>
                 {
                opt.SerializerSettings.ReferenceLoopHandling =
                    Newtonsoft.Json.ReferenceLoopHandling.Serialize;
                opt.SerializerSettings.PreserveReferencesHandling =
                    Newtonsoft.Json.PreserveReferencesHandling.Objects;
                 });

0

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


0

আমি একই সমস্যার মুখোমুখি হয়েছি এবং আমি স্বতঃপ্রকাশের ত্রুটিটিকে তার ধরণের কাজটিকে অবহেলা করার জন্য জসনসেটিংকে ব্যবহার করার চেষ্টা করেছি যতক্ষণ না আমি এমন একটি ক্লাস পেয়ে যাই যা স্ব-রেফারেন্সিং খুব গভীরভাবে হয় এবং আমার ডট-নেট প্রক্রিয়াটি জসন রাইটিংয়ের মূল্যতে ঝুলে থাকে।

আমার সমস্যা

    public partial class Company : BaseModel
{
    public Company()
    {
        CompanyUsers = new HashSet<CompanyUser>();
    }

    public string Name { get; set; }

    public virtual ICollection<CompanyUser> CompanyUsers { get; set; }
}

public partial class CompanyUser
{
    public int Id { get; set; }
    public int CompanyId { get; set; }
    public int UserId { get; set; }

    public virtual Company Company { get; set; }

    public virtual User User { get; set; }
}

public partial class User : BaseModel
{
    public User()
    {
        CompanyUsers = new HashSet<CompanyUser>();
    }

    public string DisplayName { get; set; }
    public virtual ICollection<CompanyUser> CompanyUsers { get; set; }

}

আপনি ব্যবহারকারী শ্রেণিতে সমস্যাটি দেখতে পাচ্ছেন যা এটি কোম্পানির ব্যবহারকারী শ্রেণিতে রেফারেন্স করছে যা একটি স্ব-উল্লেখযোগ্য।

এখন, আমি getAll পদ্ধতিতে কল করছি যার মধ্যে সমস্ত সম্পর্কিত বৈশিষ্ট্য রয়েছে।

cs.GetAll("CompanyUsers", "CompanyUsers.User");

এই পর্যায়ে আমার ডটনেটকোর প্রক্রিয়াটি জেসনআরসাল্ট এক্সিকিউট করা, লেখার মান ... এবং কখনই আসে না hang আমার স্টার্টআপ.সে, আমি ইতিমধ্যে জসনঅপশন সেট করেছি set কোনও কারণে ইএফসিওরে নেস্টেড সম্পত্তি রয়েছে যা আমি ইফকে দিতে বলছি না including

    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

প্রত্যাশিত আচরণ এই হওয়া উচিত

আরে এফকোর আপনি দয়া করে আমার কোম্পানির ক্লাসে "CompanyUser" ডেটা অন্তর্ভুক্ত করতে পারেন যাতে আমি সহজেই ডেটা অ্যাক্সেস করতে পারি।

তারপর

আরে এফকোর আপনি দয়া করে "CompanyUser.User" ডেটাও অন্তর্ভুক্ত করতে পারেন যাতে আমি এই কোম্পানির মতো ডেটা সহজেই অ্যাক্সেস করতে পারি omp

এই পর্যায়ে আমি শুধু এই পাওয়া উচিত "। Company.CompanyUsers.First () User.DisplayName" এবং এটি আমাকে দিতে করা উচিত নয় Company.CompanyUsers.First () User.CompanyUsers। যা স্ব-উল্লেখ ইস্যু ঘটাচ্ছে; টেকনিক্যালি এটি আমাকে ব্যবহারকারীর দেওয়া উচিত নয় U কোম্পানির ব্যবহারকারীরা নেভিগেশনাল সম্পত্তি হিসাবে কোম্পানী ব্যবহারকারীরা। তবে, এফকোর খুব উত্সাহিত হয়ে আমাকে ইউজার.কম্পানি ইউজার দিচ্ছে

সুতরাং, সম্পত্তি থেকে বাদ দেওয়ার জন্য আমি একটি এক্সটেনশন পদ্ধতি লিখতে সিদ্ধান্ত নিয়েছি (এটি আসলে বাদ দিচ্ছে না এটি কেবল সম্পত্তিটি বাতিল করে দেবে)। এটি কেবল অ্যারে বৈশিষ্ট্যগুলিতেও কাজ করবে তা নয়। নীচে কোডটি আমি অন্য ব্যবহারকারীদের জন্য ন্যুগেট প্যাকেজও রফতানি করতে যাচ্ছি (এটি এমনকি কারও সাহায্য করে কিনা তা নিশ্চিত নয়)। কারণটি সহজ কারণ আমি লিখতে খুব অলস .সামান্য নির্বাচন করুন (n => নতুন {n.p1, n.p2}); আমি কেবল 1 টি সম্পত্তি বাদ দেওয়ার জন্য নির্বাচিত বিবৃতি লিখতে চাই না!

এটি হ'ল হুট করে লিখেছি এটি সেরা কোড নয় (আমি কোনও পর্যায়ে আপডেট করব) এবং যদিও এটি এমন কোনও ব্যক্তিকে সহায়তা করতে পারে যা অ্যারে দিয়ে অবজেক্টে (নাল সেট) বাদ দিতে চায়।

    public static class PropertyExtensions
{
    public static void Exclude<T>(this T obj, Expression<Func<T, object>> expression)
    {
        var visitor = new PropertyVisitor<T>();
        visitor.Visit(expression.Body);
        visitor.Path.Reverse();
        List<MemberInfo> paths = visitor.Path;
        Action<List<MemberInfo>, object> act = null;

        int recursiveLevel = 0;
        act = (List<MemberInfo> vPath, object vObj) =>
        {

            // set last propert to null thats what we want to avoid the self-referencing error.
            if (recursiveLevel == vPath.Count - 1)
            {
                if (vObj == null) throw new ArgumentNullException("Object cannot be null");

                vObj.GetType().GetMethod($"set_{vPath.ElementAt(recursiveLevel).Name}").Invoke(vObj, new object[] { null });
                return;
            }

            var pi = vObj.GetType().GetProperty(vPath.ElementAt(recursiveLevel).Name);
            if (pi == null) return;
            var pv = pi.GetValue(vObj, null);
            if (pi.PropertyType.IsArray || pi.PropertyType.Name.Contains("HashSet`1") || pi.PropertyType.Name.Contains("ICollection`1"))
            {
                var ele = (IEnumerator)pv.GetType().GetMethod("GetEnumerator").Invoke(pv, null);

                while (ele.MoveNext())
                {
                    recursiveLevel++;
                    var arrItem = ele.Current;

                    act(vPath, arrItem);

                    recursiveLevel--;
                }

                if (recursiveLevel != 0) recursiveLevel--;
                return;
            }
            else
            {
                recursiveLevel++;
                act(vPath, pv);
            }

            if (recursiveLevel != 0) recursiveLevel--;

        };

        // check if the root level propert is array
        if (obj.GetType().IsArray)
        {
            var ele = (IEnumerator)obj.GetType().GetMethod("GetEnumerator").Invoke(obj, null);
            while (ele.MoveNext())
            {
                recursiveLevel = 0;
                var arrItem = ele.Current;

                act(paths, arrItem);
            }
        }
        else
        {
            recursiveLevel = 0;
            act(paths, obj);
        }

    }

    public static T Explode<T>(this T[] obj)
    {
        return obj.FirstOrDefault();
    }

    public static T Explode<T>(this ICollection<T> obj)
    {
        return obj.FirstOrDefault();
    }
}

উপরের এক্সটেনশান ক্লাসটি আপনাকে স্ব-রেফারেন্সিং লুপ এমনকি অ্যারেগুলি এড়ানোর জন্য সম্পত্তিটি বাতিল করে দেওয়ার ক্ষমতা দেবে।

এক্সপ্রেশন নির্মাতা

    internal class PropertyVisitor<T> : ExpressionVisitor
{
    public readonly List<MemberInfo> Path = new List<MemberInfo>();

    public Expression Modify(Expression expression)
    {
        return Visit(expression);
    }


    protected override Expression VisitMember(MemberExpression node)
    {
        if (!(node.Member is PropertyInfo))
        {
            throw new ArgumentException("The path can only contain properties", nameof(node));
        }

        Path.Add(node.Member);
        return  base.VisitMember(node);
    }
}

রীতিনীতি:

মডেল ক্লাস

    public class Person
{
    public string Name { get; set; }
    public Address AddressDetail { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public Country CountryDetail { get; set; }
    public Country[] CountryDetail2 { get; set; }
}

public class Country
{
    public string CountryName { get; set; }
    public Person[] CountryDetail { get; set; }
}

ডামি ডেটা

           var p = new Person
        {
            Name = "Adeel Rizvi",
            AddressDetail = new Address
            {
                Street = "Sydney",
                CountryDetail = new Country
                {
                    CountryName = "AU"
                }
            }
        };

        var p1 = new Person
        {
            Name = "Adeel Rizvi",
            AddressDetail = new Address
            {
                Street = "Sydney",
                CountryDetail2 = new Country[]
                {
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A1" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A2" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A3" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A4" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A5" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A6" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A7" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A8" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A9" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A1" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A2" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A3" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A4" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A5" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A6" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A7" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A8" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },
                    new Country{ CountryName = "AU", CountryDetail = new Person[]{ new Person { Name = "A9" }, new Person { Name = "A1" }, new Person { Name = "A1" } } },

                }
            }
        };

মামলা:

কেস 1: কোনও অ্যারে ছাড়াই কেবল সম্পত্তি বাদ দিন

p.Exclude(n => n.AddressDetail.CountryDetail.CountryName);

কেস 2: 1 অ্যারে দিয়ে সম্পত্তি বাদ দিন

p1.Exclude(n => n.AddressDetail.CountryDetail2.Explode().CountryName);

কেস 3: 2 নেস্টেড অ্যারে দিয়ে সম্পত্তি বাদ দিন

p1.Exclude(n => n.AddressDetail.CountryDetail2.Explode().CountryDetail.Explode().Name);

কেস ৪: অন্তর্ভুক্ত সহ ইএফ গেটএল অনুসন্ধান

var query = cs.GetAll("CompanyUsers", "CompanyUsers.User").ToArray();
query.Exclude(n => n.Explode().CompanyUsers.Explode().User.CompanyUsers);
return query;

আপনার লক্ষ্য আছে যে বিস্ফোরণ () পদ্ধতিটি এটি কেবলমাত্র আমাদের এক্সপ্রেশন বিল্ডারের অ্যারে সম্পত্তি থেকে সম্পত্তি পেতে extension যখনই কোনও অ্যারের বৈশিষ্ট্য উপস্থিত থাকে তখন .Exlode ()। YourPropertyToExclude বা। এক্সপ্লোড ()। সম্পত্তি1.MyArrayProperty.Explode ()। MyStupidProperty । উপরের কোডটি আমাকে যতটা গভীর চাই আত্ম-রেফারেন্সিং এড়াতে সহায়তা করে। এখন আমি গেটএল ব্যবহার করতে পারি এবং যে সম্পত্তিটি আমি চাই না তা বাদ দিতে পারি!

এই বড় পোস্ট পড়ার জন্য আপনাকে ধন্যবাদ!


-1

লুপ না করার জন্য এটি আমার পক্ষে কাজ করেছে-
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,

আমি এখানে সবকিছু সমাধান করেছি - নেট কোর 2 ওয়েবএপিআই https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606 দিয়ে সত্তা ফ্রেমওয়ার্ক শিশুদের সিরিয়ালকরণ

কোন মন্তব্য প্রশংসা করবে। হতে পারে যে কেউ এটি ব্যবহার করতে পারেন।


-1

সি # কোড:

            var jsonSerializerSettings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
                PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            };

            var jsonString = JsonConvert.SerializeObject(object2Serialize, jsonSerializerSettings);

            var filePath = @"E:\json.json";

            File.WriteAllText(filePath, jsonString);

এটি আট বছর আগে থেকে @ ডালসফ্টের উচ্চ-রেটে দেওয়া উত্তরে মূলত একই নির্দেশিকা, তবে এর চেয়ে কম ব্যাখ্যা সহ।
জেরেমি কেনে

আশা করি এটি সমস্যার সমাধান করবে তবে দয়া করে এটি দিয়ে আপনার কোডের ব্যাখ্যা যুক্ত করুন যাতে ব্যবহারকারী সঠিকভাবে বুঝতে পারে যা সে / সে সত্যই চায়।
জামিল প্যাটেল

-2

আমি এখানেApplication_Start() উত্তর হিসাবে এটি থেকে সমাধান যে সমাধান পছন্দ

স্পষ্টতই আমি ডালসফ্টের জবাব হিসাবে আমার ফাংশনটির মধ্যে কনফিগারেশনটি ব্যবহার করে জাভাস্ক্রিপ্টে জাসন স্ক্রিপ্টগুলিতে অ্যাক্সেস করতে পারিনি the

যাইহোক যাই হোক না কেন যা কাজ দুর্দান্ত (কারণ জিজ্ঞাসিত মন্তব্য এবং প্রশ্নগুলির উপর ভিত্তি করে বিভিন্ন দৃশ্যে বিভিন্ন পদ্ধতি কাজ করে) যদিও এটি করার একটি স্ট্যান্ডার্ড পদ্ধতি পদ্ধতির পক্ষে কিছু ভাল ডকুমেন্টেশন সমর্থন করা পছন্দনীয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.