149

我在 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.Cyber​​User”类型的属性“Cyber​​User”检测到自引用循环。路径“[0].EventRegistrations[0].Cyber​​User.UserLogs[0]”。

4

11 回答 11

294

我刚刚遇到了与父/子集合相同的问题,发现那个帖子解决了我的问题。我只想显示父集合项的列表,不需要任何子数据,因此我使用了以下内容并且效果很好:

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

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

它还引用了 Json.NET codeplex 页面:

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

文档:ReferenceLoopHandling 设置

于 2012-11-25T10:01:30.490 回答
52

解决方法是忽略循环引用而不是序列化它们。此行为在 中指定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

于 2013-09-16T16:37:18.193 回答
41

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

services.AddMvc()
    .AddJsonOptions(
        options => options.SerializerSettings.ReferenceLoopHandling =            
        Newtonsoft.Json.ReferenceLoopHandling.Ignore
    );
于 2017-07-18T18:30:49.903 回答
13

这可能会对您有所帮助。

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

于 2014-04-10T21:27:10.600 回答
7

您必须设置保留对象引用:

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

于 2017-07-25T14:02:13.140 回答
7

我正在使用 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;
                });
于 2020-01-28T16:24:38.577 回答
4

将“[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; }
}
于 2019-05-17T12:33:27.533 回答
3

对于 asp.net core 3.1.3 这对我有用

services.AddControllers().AddNewtonsoftJson(opt=>{
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });
于 2020-07-01T17:18:20.127 回答
1

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

于 2018-12-12T07:16:37.907 回答
1

有时你有循环,因为你的类型类引用了其他类,并且类引用了你的类型类,因此你必须在 json 字符串中选择你需要的参数,就像这段代码一样。

List<ROficina> oficinas = new List<ROficina>();
oficinas = /*list content*/;
var x = JsonConvert.SerializeObject(oficinas.Select(o => new
            {
                o.IdOficina,
                o.Nombre
            }));
于 2020-02-10T19:32:59.773 回答
1

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);
            }
        }
    }
于 2020-09-03T18:52:16.657 回答