유형에 대해 JSON.NET 오류 자체 참조 루프가 탐지되었습니다.
Entity Data Model .edmx 에서 자동으로 생성된 POCO 클래스를 시리얼화하려고 했는데, 이 클래스는
JsonConvert.SerializeObject
다음 오류가 발생하였습니다.
오류 System.data.entity 유형에 대해 감지된 자체 참조 루프가 발생합니다.
이 문제는 어떻게 해결하나요?
최적의 솔루션은 Web API에서의 루프 레퍼런스 처리(이 답변의 대부분은 복사)에서 얻을 수 있습니다.
수정 1: 순환 참조를 전체적으로 무시합니다.
(다른 많은 것들과 마찬가지로 이쪽도 선택/시도해 보았습니다)
net 에는 circular .json.net 을 무시하는 ., 하다, 하다, 하다.
WebApiConfig.cs삭제:config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;간단한 수정으로 시리얼라이저는 루프의 원인이 되는 참조를 무시하게 됩니다.단, 다음과 같은 제한이 있습니다.
- 데이터가 루핑 참조 정보를 손실합니다.
- 이 수정은 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 시리얼라이저도 마찬가지입니다.
수정 3: 참조 속성 무시 및 유지
이 수정은 모델 또는 속성 수준에서 직렬화 동작을 제어하기 위해 모델 클래스의 속성을 꾸미는 것입니다.속성을 무시하려면:
public class Category { public int Id { get; set; } public string Name { get; set; } [JsonIgnore] [IgnoreDataMember] public virtual ICollection<Product> Products { get; set; } }Json Ignore는 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 입 j j j j 및 「」[DataContract(IsReference = true)]「XmlDCSerializer」를 참조해 주세요. " " " 적용 후: " "DataContract'수업할 때', '할 때', '할 때'를해야 합니다.DataMember시리얼화할 속성으로 이동합니다.속성은 json 및 xml serializer 모두에 적용할 수 있으며 모델 클래스에 대한 더 많은 제어 기능을 제공합니다.
Json Serializer 설정 사용
ReferenceLoopHandling.Error(기본값)은 참조 루프가 발생하면 에러가 발생합니다.이것이 당신이 예외를 두는 이유입니다.ReferenceLoopHandling.Serialize는 오브젝트가 네스트되어 있지만 무제한이 아닌 경우에 편리합니다.ReferenceLoopHandling.Ignore는 오브젝트 자체가 하위 오브젝트인 경우 오브젝트를 시리얼화하지 않습니다.
예:
JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
});
무기한 중첩된 개체를 직렬화해야 하는 경우 PreserveObjectReferences를 사용하여 StackOverflow를 방지할 수 있습니다.예외.
예:
JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented,
new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
직렬화할 개체에 적합한 항목을 선택합니다.
레퍼런스 http://james.newtonking.com/json/help/
수정은 루프 참조를 무시하고 시리얼화하지 않는 것입니다.은 에 .JsonSerializerSettings.
과부하가 있는 싱글:
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
가장 간단한 방법은 Json을 설치하는 것입니다.NUGET에서 NET을 사용하여[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; }
요즘은 원하는 속성만 사용하여 모델을 만들고 있기 때문에 가볍고 불필요한 컬렉션을 포함하지 않으며 생성된 파일을 재구축할 때 변경 내용이 손실되지 않습니다.
.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));
});
}
사용하고 .2. NET Core 2.x ConfigureServices의 항을 참조해 주세요.Startup.cs
https://learn.microsoft.com/en-us/ef/core/querying/related-data/serialization
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
를 사용하고 있는 경우.MVC가 없는 경우 NET Core 3.x ~ 5.0은 다음과 같습니다.
# startup.cs
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
6.의 경우, 에 들어가는 입니다.NET 6.0의 경우, 유일한 차이는, 다음의 순서로 이행하는 것입니다.Program.cs.
# program.cs
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Entity Framework 및 데이터베이스 우선 설계 패턴을 사용하는 경우 이 참조 루프 처리는 거의 필수입니다.
이 두 줄을 DbContext 클래스 컨스트럭터에 추가하여 Self Referencing 루프를 비활성화할 수 있습니다.
public TestContext()
: base("name=TestContext")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
루프 문제가 있을 때 NEWONSOFTJSON에서 us를 시리얼화하기 위해 저는 global.asax나 apiconfig를 변경할 필요가 없었습니다.Json Serialize만 사용합니다.설정이 루프 처리를 무시합니다.
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var lst = db.shCards.Where(m => m.CardID == id).ToList();
string json = JsonConvert.SerializeObject(lst, jss);
을 사용법[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...
}
도움이 되길 바래, 얀스
루프 참조를 무시하고 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);
});
}
서비스 업데이트만 하면 됩니다.Startup.cs 파일의 AddControllers()
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
을 「 」에서 사용합니다.WebApiConfig.cs: 클클 :
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
나는 다른 길을 가야 했다.JSON을 수정하는 대신Net serializer 나는 내 datacontext의 Lazy Loading을 따라가야 했다.
방금 기본 저장소에 추가했습니다.
context.Configuration.ProxyCreationEnabled = false;
"context" 개체는 종속성 주입을 사용하기 때문에 기본 저장소에서 사용하는 생성자 매개 변수입니다.대신 데이터를 인스턴스화하는 모든 위치에서 ProxyCreationEnabled 속성을 변경할 수 있습니다.
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
이 예외는 있었습니다만, 운용 솔루션은 「간단하고 심플한」입니다.
참조된 속성에 JsonIgnore 속성을 추가하여 무시합니다.
[JsonIgnore]
public MyClass currentClass { get; set; }
역직렬화 시 속성을 리셋합니다.
Source = JsonConvert.DeserializeObject<MyObject>(JsonTxt);
foreach (var item in Source)
{
Source.MyClass = item;
}
뉴튼소프트를 사용해서요.Json;
팀:
이것은 ASP에서 동작합니다.NET Core: 위의 과제는 '무시하도록 설정을 설정하는 방법'입니다.애플리케이션의 셋업 방법에 따라서는, 매우 어려운 일이 있습니다.여기 나에게 효과가 있었던 것이 있다.
이것은, 고객의 퍼블릭의 무효 설정 서비스( )에 넣을 수 있습니다.IService Collection services) 섹션.
services.AddMvc().AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
클래스의 가상 속성에 [JsonIgnore]가 추가되는 것에 대해 이미 언급되어 왔습니다.다음은 예를 제시하겠습니다.
[JsonIgnore]
public virtual Project Project { get; set; }
또 다른 옵션 [JsonProperty(NullValueHandling)= NullValueHandling]도 공유하겠습니다.Ignore)]는 늘인 경우에만 속성을 시리얼라이제이션에서 제외합니다.
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public virtual Project Project { get; set; }
.Net 5.x에서 startup.cs의 ConfigureServices 메서드를 다음 코드로 업데이트합니다.
public void ConfigureServices(IServiceCollection services)
{
----------------
----------------
services.AddMvc().AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
});
------------------
}
디폴트로는 시리얼라이제이션(시스템).텍스트, Json.직렬화)는 주기가 있는 개체를 지원하지 않으며 중복 참조를 보존하지 않습니다.Serialization 및 메타데이터 사용 시 고유한 개체 참조 보존을 사용하도록 설정하여 Disserialization 시 보존된 참조를 읽습니다.MSDN 링크
커스텀 구성 Json Serializer 설정으로 해결된 문제:
services.AddMvc(
// ...
).AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Serialize;
opt.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.Objects;
});
.NET Core 3.0의 경우 다음과 같이 Startup.cs 클래스를 업데이트합니다.
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/
또한 wait와 async도 반드시 사용하세요.개체가 제대로 일련화되지 않은 경우 이 오류가 발생할 수 있습니다.
C# 코드:
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);
「 」를 붙이기만 .Configuration.ProxyCreationEnabled = false;콘텍스트 파일 내에 있습니다.이것에 의해, 문제가 해결됩니다.
public demEntities()
: base("name=demEntities")
{
Configuration.ProxyCreationEnabled = false;
}
저도 같은 문제에 직면해 있었고, Json Setting을 사용하여 자기 참조 오류를 무시하려고 했습니다.자기 참조가 매우 깊고, 닷넷 프로세스가 Json의 쓰기 값에 의존하는 클래스를 받을 때까지, 어느 정도 효과가 있었습니다.
내 문제
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; }
}
사용자 클래스에서 문제를 확인할 수 있습니다.이 클래스는 자체 참조인 Company User 클래스를 참조합니다.
이제 모든 관계 속성을 포함하는 GetAll 메서드를 호출합니다.
cs.GetAll("CompanyUsers", "CompanyUsers.User");
이 단계에서 DotNetCore 프로세스는 JsonResult 실행, 값 쓰기...에 의존하며 절대 실행되지 않습니다.Startup.cs에서 Json Option을 이미 설정했습니다.어떤 이유에서인지 EFCore는 내가 Ef에게 주지 말라고 한 중첩된 재산을 포함하고 있다.
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
예상되는 동작은 다음과 같아야 합니다.
EfCore 씨, 제가 데이터에 쉽게 액세스할 수 있도록 "CompanyUsers" 데이터도 회사 클래스에 포함시켜 주시겠습니까?
그리고나서
EfCore 씨, "CompanyUsers"도 포함시켜 주세요.사용자" 데이터도 이 회사처럼 쉽게 액세스할 수 있습니다.Company Users(회사 사용자)첫 번째()입니다.User.DisplayName
이 단계에서는 이 "Company"만 받습니다.Company Users(회사 사용자)첫 번째()입니다.User.DisplayName"을 클릭하면 Company가 표시되지 않습니다.Company Users(회사 사용자)첫 번째()입니다.User.Company 사용자로 인해 자기 참조 문제가 발생합니다.엄밀히 말하면, 유저라고는 할 수 없습니다.CompanyUsers(CompanyUsers)는 네비게이션 속성입니다.그러나 EfCore는 매우 흥분하여 사용자 정보를 제공합니다.Company Users(회사 사용자)
그래서 오브젝트에서 제외되는 확장 메서드를 작성하기로 했습니다(실제로 제외되는 것이 아니라 속성을 null로 설정합니다).어레이 속성에서도 동작할 뿐만 아니라, 이하에 Nuget 패키지를 다른 유저용으로 export 하는 코드를 나타냅니다(이것이 도움이 될지 어떨지는 잘 모르겠습니다).이유는 간단하다. 왜냐하면 나는 글을 쓰는 것이 너무 귀찮기 때문이다.선택(n => 새 {n.p1, n.p2}); 하나의 속성만 제외하기 위해 선택 문을 쓰지 않습니다!
이 코드는 최적의 코드가 아닙니다(나중에 업데이트하겠습니다).다만, 어레이가 있는 오브젝트에서 제외(null로 설정)하는 사용자에게 도움이 될 수도 있습니다.
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();
}
}
위의 확장 클래스는 자기 소싱 루프 짝수 배열을 피하기 위해 속성을 null로 설정하는 기능을 제공합니다.
식 빌더
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);
케이스 4: EF GetAll 쿼리(포함
var query = cs.GetAll("CompanyUsers", "CompanyUsers.User").ToArray();
query.Exclude(n => n.Explode().CompanyUsers.Explode().User.CompanyUsers);
return query;
Plaste() 메서드는 어레이 속성에서 속성을 가져오는 식 빌더만의 확장 메서드이기도 합니다.배열 속성이 있는 경우 를 사용합니다.폭발().Your Property To Exclude 또는.폭발().프로퍼티My Array Property.폭발().My Stupid Property.위의 코드는 내가 원하는 만큼 깊이 자기 참조를 피할 수 있도록 도와준다.이제 GetAll을 사용하여 원하지 않는 속성을 제외할 수 있습니다!
이 큰 글을 읽어주셔서 감사합니다!
데이터 모델을 웹 페이지에 제공하는 데이터베이스 응용 프로그램을 상속했습니다.디폴트로는 시리얼화는 모델트리 전체를 통과하려고 합니다.이 답변의 대부분은 이를 방지하는 방법에 대한 좋은 시작입니다.
아직 검토되지 않은 옵션 중 하나는 인터페이스를 사용하는 것입니다.앞의 예에서 훔치겠습니다.
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 interface IgnoreUser
{
[JsonIgnore]
User User { get; set; }
}
public interface IgnoreCompany
{
[JsonIgnore]
User User { get; set; }
}
public partial class CompanyUser : IgnoreUser, IgnoreCompany
{
}
상기 솔루션에서는 Json 설정이 손상되지 않습니다.LazyLoadingEnabled 및 ProxyCreationEnabled를 false로 설정하면 모든 백엔드 코딩에 영향을 미쳐 ORM 툴의 진정한 이점을 얻을 수 없게 됩니다.응용 프로그램에 따라 LazyLoading/ProxyCreation 설정은 수동으로 로드하지 않고 탐색 속성을 로드하지 못하도록 할 수 있습니다.
다음은 내비게이션 속성이 직렬화되는 것을 방지하는 훨씬 더 나은 솔루션이며 표준 json 기능을 사용합니다.JSON 시리얼라이저가 내비게이션 속성을 무시하려면 어떻게 해야 합니까?
여기에 나와 있는 다른 것과 매우 유사하며, 시리얼라이저 설정을 사용하여 해결됩니다.하지만 제 것은 FromObject를 사용할 때 JObject가 필요했기 때문에 FromObject를 사용할 때부터 시작되었습니다.
즉, 기본 시리얼라이저를 생성하여 설정을 적용하기만 하면 됩니다.간단한 수정은 이렇게 됩니다.
var deserializerSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
};
var serializer = JsonSerializer.CreateDefault(deserializerSettings);
JObject jsonObject = (JObject)JToken.FromObject(mySelfRefernceObject, serializer);
않았기 에, 가 있었다.
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
여기서 모두 해결했습니다.Entity Framework의 아동 시리얼화입니다.Net Core 2 WebAPI https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606
어떤 발언이라도 해주시면 감사하겠습니다. 언젠가 누군가 쓸 수 있을 겁니다.
는 그것을 이 마음에 .Application_Start()여기 대답과 같이
오브젝트의 (키, val) 전체에 "\n\r"이 반환된 오브젝트이기 때문에 DalSoft의 응답과 같이 기능 내의 Configuration을 사용하여 JavaScript의 json 오브젝트에 액세스할 수 없었던 것 같습니다.
어쨌든 효과가 있는 것은 훌륭하지만(물어본 코멘트나 질문에 근거해 다른 시나리오에서 다른 접근방식이 동작하기 때문에), 표준적인 방법이 그 접근방식을 뒷받침하는 좋은 문서와 함께 바람직하다.
언급URL : https://stackoverflow.com/questions/7397207/json-net-error-self-referencing-loop-detected-for-type
'programing' 카테고리의 다른 글
| Angular ui-grid 선택 항목을 어디서 가져올 수 있습니까? (0) | 2023.03.26 |
|---|---|
| 직렬화 가능한 python 객체의 json 인코딩 동작을 변경하는 방법은 무엇입니까? (0) | 2023.03.26 |
| 봄에 동적 HTML 응답을 최소화하려면 어떻게 해야 합니까? (0) | 2023.03.21 |
| 문자 영역(material-ui) (0) | 2023.03.21 |
| Wordpress : taxonomy.php에서 분류명을 취득하려면 어떻게 해야 합니까? (0) | 2023.03.21 |