使用 Newtonsoft JSON 序列化循环引用



我正在尝试序列化和反序列化的实体:

public class Car
{
    public string Model { get; set; }
    public DateTime Year { get; set; }
    public List<string> Features { get; set; }
    private Car _car;
    public Car Car1
    {
        get
        {
            return _car != null ? _car : new Car();
        }
        set
        {
            _car = value;
        }
    }
}

我正在使用牛顿软件 Json 库来序列化和反序列化上述实体。在序列化和反序列化此实体时,我不能忽略任何属性。

在序列化实体时,立即引发堆栈溢出异常。

JsonConvert.SerializeObject(car)

大多数其他地方都提到了使用以下解决方案,但没有一个对我有用。

var _jsonSettings = new JsonSerializerSettings()
{
    TypeNameHandling = TypeNameHandling.Auto,
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
    PreserveReferencesHandling = PreserveReferencesHandling.Objects,
    ObjectCreationHandling = ObjectCreationHandling.Auto
};
var settings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
var serialize = JsonConvert.SerializeObject(car, _jsonSettings);
or
var serialize = JsonConvert.SerializeObject(car, settings);

我知道问题出在这家酒店

private Car _car;
    public Car Car1
    {
        get
        {
            return _car != null ? _car : new Car();
        }
        set
        {
            _car = value;
        }
    }

但我暂时无法摆脱它。

修改后的问题:

public interface IEntity
    {
        int Id { get; set; }
    }
    public class Base1 : IEntity
    {
        public virtual int Id { get; set; }
    }
public class Car : Base1
    {//same properties as defined above in above Car class + below property
        private int _carId;
        public int CarId
        {
            get { return _carId; }
            set { _carId = value; Id = value; }
        }
    }
            var car = new Car();
            car.Model = "Amaze";
            car.Year = new DateTime(2016, 1, 1);
            car.Features = new List<string> { "Light", "1", "2" };
            car.CarId = 1;

在这里,基类的 Id 将始终为零,派生始终设置非零值。是否可以编写自定义转换器(通过检查属性 ID 的值是否为零,然后不要进一步序列化该属性(Car1 属性(?任何建议,如何实现?

您遇到此问题的原因有两个:

return _car != null ? _car : new Car();

如果 _car 的值为 null,则每次都会返回一个新实例,这会将序列化程序发送到导致溢出的无限遍历中。

你需要重新考虑你的设计。您应该将新实例分配给内部变量,否则您将丢失引用并继续具有null

public Car Car1
{
    get
    {
        if(_car == null)
            _car = new Car();
        return _car;
    }
    set
    {
        _car = value;
    }
}

但是,这种自动初始化将继续是一个问题,因为总会有一个值要序列化。如果不存在任何对象,则应null该值,这将允许序列化程序完成其工作并到达对象图的末尾。

最新更新