【问题标题】:JSON.NET Deserialization is not triggering setterJSON.NET 反序列化未触发 setter
【发布时间】:2017-03-09 21:37:56
【问题描述】:

我有一个从列表派生的类,无论我做什么,我都找不到 JSON.NET 设置值的位置。在我看来,即使是标记的属性也没有触发。

我在以下所有区域都设置了断点:

public CartItem Add(int id, int numItems, CARTITEMTYPE type = CARTITEMTYPE.GENERIC)
    {
        var item = NewByType(type);
        item.ID = id;
        item.NumItems = numItems;
        return this.Add(item);
    }

    public new CartItem Add(CartItem item)
    {
        item.Parent = this;
        base.Add(item);
        return item;
    }

    public new void AddRange(IEnumerable<CartItem> items)
    {
        items.Any(f => { f.Parent = this; return true; });
        base.AddRange(items);
    }

    public new void InsertRange(int index, IEnumerable<CartItem> items)
    {
        items.Any(f => { f.Parent = this; return true; });
        base.InsertRange(index, items);
    }

    public new CartItem Insert(int index, CartItem item)
    {
        item.Parent = this;
        base.Insert(index,item);
        return item;
    }

但这些都没有在运行反序列化时触发中断。

反序列化过程相对简单,使用这个:

    public T GetJObject<T>(string cookieName, JsonSerializerSettings jset = null)
    {
        string cookieContent = Get(cookieName);
        return JsonConvert.DeserializeObject<T>(cookieContent, jset);
    }

而且转换器类也很简单:

public class JsonCartConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(CartItem).IsAssignableFrom(objectType);
    }

    public override bool CanWrite
    {
        get
        {
            return false;
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);

        var type = obj["t"] != null ? (CARTITEMTYPE)obj["t"].Value<int>() : CARTITEMTYPE.GENERIC;
        var item = CartItems.NewByType(type);
        serializer.Populate(obj.CreateReader(), item);
        return item;
    }


    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

    }
}

即使在其他类中标有 JsonProperty 的区域也不会在反序列化时受到影响。

[JsonProperty("c")]
    public CartItems Children
    {
        get
        {
            if (_Children == null) _Children = new CartItems();
            if (_Children.Parent == null) _Children.Parent = this;
            _Children.SiteID = SiteID;
            _Children.UserID = UserID;
            return _Children;
        }
        set
        {
            Children.Parent = this;
            Console.WriteLine("we set the parent");
            _Children = value;
        }
    }

那么 JSON.NET 是如何处理 setter 和列表的呢?显然,两者都没有被击中?我可以强制它达到设置器逻辑吗?

编辑:JSON

[{"t":1,"i":1,"n":4,"r":false,"c":[{"t":5,"i":2,"n":4,"r":false,"c":[]}]},{"t":1,"i":3,"n":4,"r":false,"c":[{"t":5,"i":4,"n":4,"r":false,"c":[{"t":4,"i":6,"n":14,"r":false,"c":[]}]},{"t":1,"i":5,"n":15,"r":false,"c":[]}]}]

【问题讨论】:

  • 那么它是否击中了其中任何一个?通过检查生成的类,最后一个示例的设置器似乎没有被击中?我从来没有看到父母被设置...
  • 它是否使用反射来绕过设置器逻辑,并通过将值强制到私有属性中来完全绕过类中的标准添加/插入功能?
  • JSON.NET 不会在您的对象上调用任何“添加/插入”方法。
  • @HristoYankov 这没有任何意义。它怎么会知道将它插入哪个私有字段?它必须调用setter。我同意它使用反射,是的,但它使用反射来调用属性设置器。
  • @dman2306,对不起,你是对的。我刚试过。在调试期间,我的设置器中的断点被击中。我将删除我的评论以避免进一步混淆。

标签: c# json.net


【解决方案1】:

我知道它在 CartItem 类中附加子项的方式(OP 中的最后一个示例)。它从不调用 setter,因为它使用 getter 获取类,然后从那里填充它。 ...当然,子类的父类必须附加属性 [JsonIgnore]。

我仍然不确定如何拦截类的填充以设置其子级的父级:

Public CartItems : List<CartItem>

关于反序列化设置子项的 Parent 属性,但这是二选一的答案。

编辑:dbc 在这里回答了第二个问题:

Intercept list population to assign values in deserialization

【讨论】:

猜你喜欢
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多