json - self referencing loop detected for property




JSON.NET 오류 유형에 대해 자체 참조 루프가 감지되었습니다. (12)

.NET Core 1.0에서는 Startup.cs 파일에서이 설정을 전역 설정으로 지정할 수 있습니다.

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));
        });
    }

엔티티 데이터 모델 .edmx에서 자동으로 생성 된 POCO 클래스를 직렬화하려고했는데 사용했을 때

JsonConvert.SerializeObject 

다음과 같은 오류가 발생했습니다.

오류 System.data.entity 유형에 대해 자체 참조 루프가 감지되었습니다.

이 문제를 어떻게 해결합니까?



그게 최고의 솔루션이었다 https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7

수정 사항 1 : 전역 참조 무시

(나는 이것을 선택 / 시도했다. 다른 많은 것들도있다.)

json.net 시리얼 라이저에는 순환 참조를 무시할 수있는 옵션이 있습니다. WebApiConfig.cs 파일에 다음 코드를 WebApiConfig.cs 하십시오.

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

간단한 수정은 serializer가 루프를 일으킬 참조를 무시하도록합니다. 그러나 한계가 있습니다.

데이터가 순환 참조 정보를 잃습니다. 수정 사항은 JSON.net에만 적용됩니다. 참조 참조 체인이 깊다면 참조 레벨을 제어 할 수 없습니다

비 -API ASP.NET 프로젝트에서이 픽스를 사용하려면 위의 행을 Global.asax.cs 추가 할 수 있지만 먼저 다음을 추가하십시오.

var config = GlobalConfiguration.Configuration;

.Net Core 프로젝트에서 이것을 사용하려면 다음과 같이 Startup.cs 를 변경할 수 있습니다.

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

수정 2 : 전역 참조 보존

이 두 번째 수정은 첫 번째 수정과 유사합니다. 코드를 다음과 같이 변경하십시오.

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"
   }
]

$ id 및 $ ref는 모든 참조를 유지하고 객체 그래프 수준을 평평하게 만듭니다. 그러나 클라이언트 코드는 데이터를 사용하기 위해 모양 변경을 알아야하며 JSON.NET serializer에도 적용됩니다.

수정 3 : 참조 속성 무시 및 보존

이 수정은 모델 또는 속성 수준에서 serialization 동작을 제어하기 위해 모델 클래스의 특성을 장식합니다. 속성을 무시하려면 다음과 같이하십시오.

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

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

JsonIgnore는 JSON.NET 용이고 IgnoreDataMember는 XmlDCSerializer 용입니다. 참조를 유지하려면 :

 // 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)] 는 XmlDCSerializer 용입니다. 참고 : 클래스에 DataContract 를 적용한 후에는 직렬화하려는 속성에 DataMember 를 추가해야합니다.

이 속성은 json과 xml serializer 모두에 적용될 수 있으며 모델 클래스에 대한 더 많은 컨트롤을 제공합니다.


나에게는 다른 길로 가야했다. JSON.Net 시리얼 라이저를 수정하는 대신 내 datacontext에 Lazy Loading을 수행해야했다.

방금 기본 저장소에 추가했습니다.

context.Configuration.ProxyCreationEnabled = false;

"컨텍스트"객체는 의존성 주입을 사용하기 때문에베이스 리포지토리에서 사용하는 생성자 매개 변수입니다. 대신 datacontext를 인스턴스화하는 모든 위치에서 ProxyCreationEnabled 속성을 변경할 수 있습니다.

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


루프 문제가있을 때 NEWTONSOFTJSON을 직렬화하려면 필자의 경우 global.asax 또는 apiconfig를 수정할 필요가 없습니다. 루프 처리를 무시하고 JsonSerializesSettings를 사용합니다.

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

루프 참조를 무시하고 MVC 6에서 전역으로 직렬화하지 않으려면 startup.cs에서 다음을 사용하십시오.

    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);
        });
    }

사람들은 클래스의 가상 속성에 추가 할 [JsonIgnore]에 대해 이미 이야기했습니다. 예를 들면 다음과 같습니다.

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

또 하나의 옵션 인 [JsonProperty (NullValueHandling = NullValueHandling.Ignore)]을 공유 할 것입니다.이 옵션은 null 일 경우에만 직렬화에서 속성을 생략합니다.

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

속성에 속성을 적용 할 수도 있습니다. [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...    
}

희망은 도움이된다, Jaans


이 두 줄을 DbContext 클래스 생성자에 추가하여 자기 참조 루프를 비활성화 할 수 있습니다.

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

이 예외가 있었고 제 작업 솔루션이 쉽고 간단했습니다.

JsonIgnore 특성을 추가하여 Referenced 속성을 무시합니다.

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

비 직렬화 할 때 속성을 재설정하십시오.

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

Newtonsoft.Json을 사용하여;


Application_Start() 에서 응답을 얻는 해결책이 here

분명히 개체의 (키, 발) 위에 "\ n \ r"반환 된 개체로 DalSoft 응답에서 내 함수 내에서 구성을 사용하여 JavaScript json 개체를 액세스 할 수 없습니다.

어쨌든 어떤 작품이든간에 (다른 접근법은 질문과 질문에 따라 다른 시나리오에서 작동하기 때문에) 표준 방식을 사용하는 것이 접근법을 뒷받침하는 훌륭한 문서로 선호 될 것입니다.


WebApiConfig.cs 클래스에서 WebApiConfig.cs 사용하십시오 :

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




json.net