我的网站有一个 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"的自引用循环。网络用户'。 路径 '[0]。事件注册[0]。CyberUser.UserLogs[0]'.
我只是在父/子集合中遇到了同样的问题,并找到了解决我情况的帖子。我只想显示父集合项的列表,不需要任何子数据,因此我使用了以下内容,它工作正常:
JsonConvert.SerializeObject(ResultGroups, Formatting.None,
new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
JSON.NET 检测到类型的错误自引用循环
它还引用了位于以下位置的 Json.NET Codeplex 页面:
http://json.codeplex.com/discussions/272371
文档:引用循环处理设置
解决方法是忽略循环引用,而不是序列化它们。此行为在 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
如果使用 ASP.NET 核心MVC,请将以下内容添加到启动.cs文件的ConfigureServices方法中:
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
这可能会对您有所帮助。
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
必须设置"保留对象引用":
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
我正在使用 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;
});
asp.net 核心 3.1.3 这对我有用
services.AddControllers().AddNewtonsoftJson(opt=>{
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
将"[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; }
}
可以将 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);
}
}
}
如果您像我一样并且以前使用转换器调用 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));
JsonConvert.SerializeObject(ObjectName, new JsonSerializerSettings(){
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
Formatting = Formatting.Indented
});
有时你的类型类有对其他类的引用,并且这些类有对类型类的引用,因此你必须在 json 字符串中选择你需要的参数,就像这段代码一样。
List<ROficina> oficinas = new List<ROficina>();
oficinas = /*list content*/;
var x = JsonConvert.SerializeObject(oficinas.Select(o => new
{
o.IdOficina,
o.Nombre
}));
确保您没有错过任何等待关键字
如果您犯了一个愚蠢的错误,例如忘记await
异步方法,则可能会出现此错误。
public async Task<JsonResult> GetTaxTable([FromServices] TaxService taxService)
{
var taxTable = /* await */ taxService.GetTaxTable();
return new JsonResult(taxTable);
}
鉴于GetTaxTable
是一个异步函数,如果你忘记await
它,你会无意中最终将Task
传递给JsonResult
构造函数 - 并且 Task 不可序列化,所以虽然乍一看好像一切都在你身上爆炸了 - 简单的解决方案就是添加await
。