检测到 JSON.Net 自引用循环

我有一个 mssql 数据库为我的网站在4个表。

当我使用这个:

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

代码导致以下错误:

异常: 检测到类型为“ DAL.CyberUser”的属性“ CyberUser”的自引用循环。 路径’[0] . EventRegistry [0] . CyberUser. UserLogs [0]’。

191312 次浏览

我只是有同样的问题与家长/儿童收集和发现的职位,已经解决了我的情况。 我只想显示父集合条目的列表,并不需要任何子数据,因此我使用了下面的代码,它工作得很好:

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

NET 错误自引用循环检测到的类型

它还提到了 Json.NET co价值链页面:

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

文件: ReferenceLoopHandlingIgnore.htm (参考循环处理设置)

修正方法是忽略循环引用,而不是序列化它们。这个行为在 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

这个可能对你有帮助。

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

如果使用 ASP.NET Core MVC,将其添加到 startup.cs 文件的 ConfigureServices 方法中:

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

必须设置保留对象引用:

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

JsonConvert.SerializeObject (ObjectName,new JsonSerializerSettings (){ 对象, 格式化 = 缩进格式化 }) ;

向模型类中添加“[ 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; }
}

我正在使用 Dot. Net Core 3.1,并且搜索了

“ Newtonsoft. Json.JsonSerializationException: 检测到属性的自引用循环”

我在这个问题上加上这一点,因为这将是一个简单的参考。 您应该在 Startup.cs 文件中使用以下内容:

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

有时会出现循环,因为类型类具有对其他类的引用,并且类具有对类型类的引用,因此必须在 json 字符串中选择所需的参数,如下面的代码所示。

List<ROficina> oficinas = new List<ROficina>();
oficinas = /*list content*/;
var x = JsonConvert.SerializeObject(oficinas.Select(o => new
{
o.IdOficina,
o.Nombre
}));

对于 asp.net 核心3.1.3,这对我很有用

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

可以将 JsonSerializer 实例配置为忽略引用循环。如下所示,这个函数允许保存包含 json 序列化对象内容的文件:

    public static void SaveJson<T>(this T obj, string FileName)
{
   

JsonSerializer serializer = new JsonSerializer();
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
using (StreamWriter sw = new StreamWriter(FileName))
{
using (JsonWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
serializer.Serialize(writer, obj);
}
}
}

确保您没有丢失任何等待关键字

如果您犯了一个愚蠢的错误,比如忘记使用 await异步方法,您可能会得到这个错误。

    public async Task<JsonResult> GetTaxTable([FromServices] TaxService taxService)
{
var taxTable = /* await */ taxService.GetTaxTable();
return new JsonResult(taxTable);
}

考虑到 GetTaxTable是一个异步函数,如果你忘记了 await,你就会不经意地将一个 Task传递给 JsonResult构造函数——一个 Task 是不可序列化的,所以一开始看起来好像所有的东西都在你身上爆炸了——简单的解决方案就是添加 await

如果您像我一样,以前使用转换器调用 SerializeObject,那么您需要删除转换器参数并将其添加到您的配置中... ... 像这样:

var isoConvert = new IsoDateTimeConverter();
isoConvert.DateTimeFormat = _dateFormat;
List<JsonConverter> converters = new List<JsonConverter>();
converters.Add(isoConvert);
JsonSerializerSettings settings = new JsonSerializerSettings()
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Converters = converters
};


// Old Code:
//response.Write(JsonConvert.SerializeObject(Data, isoConvert);
response.Write(JsonConvert.SerializeObject(Data, settings));