2016-03-08 59 views
4

我的模型类循环引用的样子如下:处理与Newtonsoft JSON

public class ModelType 
{ 
    public string Name { get; set; } 
    public ModelType SuperType { get; set } 
    public IEnumerable<ModelType> SubTypes { get; set; } 
} 

我试图序列化对象,但得到StackOverflowException。我曾试着打电话给

JsonConvert.SerializeObject(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); 

以及

JsonConvert.SerializeObject(model, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); 

两个调用导致StackOverflowException。任何想法如何序列化ModelType实例?

EDIT

实例的实施例,从而未能序列:

{ 
    Name: "Child", 
    SuperType: { 
     Name: "Parent", 
     SuperType: null, 
     SubTypes: [{ 
       Name: "Child", 
       SuperType: { 
        Name: "Parent", 
        SuperType: null, 
        SubTypes: [{Name: "Child", ...}] 
       }, 
       SubTypes: [] 
     }] 
    }, 
    SubTypes: [] 
} 

EDIT2

通过进一步寻找到的问题(如所有SO Q &甲,设置要么ReferenceLoopHandling.IgnorePreserveReferencesHandling.Objects应该工作)我已经发现,

  1. 儿童是唯一的对象实例
  2. Child.SuperType(父)是唯一的对象实例
  3. Child.SuperType.SubTypes [0](儿童)是唯一的对象实例,而不是(1参考。 )
  4. Child.SuperType.SubTypes [0] .SuperType(母公司)是独一无二的对象实例,而不是(2)
  5. 等等的参考...

我认为,出事在对象期间错误c反应(从我的代码中),并创建了无限的对象链。我不确定这是否可以仅由JsonSerializerSettings来处理。

+0

添加了填充对象的示例。 – mimo

+0

你有一个完整的C#repro,编译的东西。 –

+0

@Simon Mourier,我很抱歉,但不能提供编译的代码,它太复杂了(通过实体框架 - >获取数据实体 - >转移到商业实体)。但我认为我找到了根本原因。当数据实体被转换为业务实体时,通过Lync查询设置SuperType和SubTypes的属性来创建这个无限链,这将在序列化时进行评估。 – mimo

回答

4

Newtonsoft.Json可以有以下配置

JsonSerializerSettings sets = new JsonSerializerSettings 
    { 
     PreserveReferencesHandling = PreserveReferencesHandling.Objects 
    }; 

    var ser = JsonSerializer.Create(sets); 

你可能想这样做。

+0

我试过了,但它不适合我。仍然得到'StackOverflowException'。 – mimo

+1

@mimo - 你看这里吗? http://stackoverflow.com/questions/25853407/json-net-not-respecting-preservereferenceshandling-on-deserialization –

+0

我看过问题,并试图使用相同的'JsonSerializerSettings'在建议的答案,但它不工作我。大多数解决方案指出,“PreserveReferencesHandling = PreserveReferencesHandling.Objects'应该可以处理这种情况,但它并不适用于我的情况。 – mimo