【问题标题】:newtonsoft.json ShouldSerialize property working but ShouldDeserialize not workingnewtonsoft.json ShouldSerialize 属性工作但 ShouldDeserialize 不工作
【发布时间】:2022-01-25 15:36:09
【问题描述】:

在我的代码中,我想使用 ShouldDeserialize 方法来使我的响应更清晰,但是对于反序列化方法,ShouldDeserialize{Property} 方法是不可见的。在下面的代码中,ShouldSerializeItems 谓词有效。

public class ItemsContainer
{
    public string Id { get; set; }

    [JsonProperty]
    public IEnumerable<Item> Items{ get; set; }
    //Working
    public bool ShouldSerializeItems()
    {
        return !Items.All(x =>
            string.IsNullOrEmpty(x.ItemName) && string.IsNullOrEmpty(x.ItemId));
    }
    // Not working
    public bool ShouldDeserializeItems()
    {
        return !Items.All(x =>
            string.IsNullOrEmpty(x.ItemName) && string.IsNullOrEmpty(x.ItemId));
    }
}

并调用反序列化:

JsonConvert.DeserializeObject<ItemsContainer>(json);

在 newtonsoft 文档中记录了序列化和反序列化谓词:

【问题讨论】:

  • 你也必须发布你的json。
  • ShouldDeserialize 未实现 stackoverflow.com/questions/35502152/…
  • @PeterCsala 它不适用于我测试的任何属性。所以我会说它不是
  • 没错,检查名为 ShouldDeserializeXXX() 的属性并自动调用它从未实现过,可能是因为 XmlSerializer 只支持 ShouldSerializeXXX(),而 Json.NET 功能就是以此为模型的。见:Conditional serialization/deserialization of object properties with json.net。基础设施就在那里,所以如果需要,您可以自己做。
  • 现在我查看了您的代码,您的方法ShouldDeserializeItems() 假定Items 已经反序列化。 Json.NET 的ShouldDeserialize 函数被称为 before 反序列化,而不是之后。您应该在反序列化后使用[OnDeserialized] 回调清除不需要的项目。

标签: c# json.net asp.net-core-3.1


【解决方案1】:

检查名为 ShouldDeserialize*() 的属性并自动调用它从未由 Json.NET 实现。请参阅:Conditional serialization/deserialization of object properties with json.net。基础设施就在那里,因此您可以通过实现覆盖DefaultContractResolver.CreateProperty() 并设置JsonProperty.ShouldDeserialize 的custom contract resolver 自己完成。

话虽如此,您的方法ShouldDeserializeItems() 似乎假设Items 已经被反序列化,然后根据一些自定义逻辑将它们过滤掉。 Json.NET 的 JsonProperty.ShouldDeserialize 谓词称为 before 反序列化,而不是之后。当它返回 true 时,JSON 属性被跳过,无法检查内容,因此不能在此处使用。

相反,您应该使用[OnDeserialized] 回调在反序列化后清除不需要的项目:

[System.Runtime.Serialization.OnDeserialized]
private void OnDeserializedMethod(System.Runtime.Serialization.StreamingContext context)
{       
    if (Items != null && Items.All(x =>
        string.IsNullOrEmpty(x.ItemName) && string.IsNullOrEmpty(x.ItemId)))
        Items = new List<Item>();
}

【讨论】:

    【解决方案2】:

    但是当您要反序列化 ItemContainer 的 Items 属性时,Items 属性中可能还没有任何内容。您可能不需要此谓词,因为如果 ShouldSerialize 正常工作,您将永远不会有垃圾数据需要反序列化。

    【讨论】:

      猜你喜欢
      • 2020-10-19
      • 1970-01-01
      • 2017-12-02
      • 2021-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      相关资源
      最近更新 更多