JSON.Net 检测到自引用循环



我的网站有一个 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

相关内容

  • 没有找到相关文章

最新更新