c# - 使用 System.Text.Json 的自定义类型继承 Dictionary 的序列化不会序列化其他属性

标签 c# json serialization .net-5 system.text.json

我有以下类型:

public class Product : Dictionary<string, object>
{
    [JsonInclude]
    public string ProductId { get; set; }

    public Product(string productId) : base()
    {
        ProductId = productId;
    }
}

使用 System.Text.Json 进行序列化时,它不包含属性(即 ProductId)。 添加或删除 [JsonInclude] 似乎没有任何效果。

测试用例:

[Fact]
public void SimpleTest()
{
    var p = new Product("ABC123");
    p["foo"] = "bar";
    var json = JsonSerializer.Serialize(p);
    Assert.Contains("productId", json, StringComparison.OrdinalIgnoreCase);
}

并收到输出:

{"foo":"bar"}

如何让它在序列化期间将我的自定义属性包含在我的类型中? (注意:不要关心反序列化)。

最佳答案

System.Text.Json不序列化字典属性。 我在 MSFT 文档中找不到任何地方说明了这一点,但是 System.Text.Json仅序列化字典键和值。这可以从 DictionaryOfTKeyTValueConverter<TCollection, TKey, TValue> 的引用来源得到证实。 ,这是用于您的类型的转换器。

这可能是因为:

  1. 可能存在与属性同名的键。
  2. 应用程序开发人员几乎肯定不想要像 Count 这样的“标准”字典属性和 IsReadOnly将被连载。
  3. 早期序列化器的行为方式与 System.Text.Json 相同正在遵循先例。 Newtonsoft 是 documented to only serialize dictionary keys and values . DataContractJsonSerializer (与 UseSimpleDictionaryFormat = true )和 JavaScriptSerializer也做。

作为替代方案,您可以考虑使用不同的数据模型,其中 Product不继承自 Dictionary而是有一个 [JsonExtensionData] public Dictionary<string, object> Properties { get; set; }属性:

public class Product 
{
    public string ProductId { get; set; }

    [System.Text.Json.Serialization.JsonExtensionData]
    public Dictionary<string, object> Properties { get; set; } = new ();

    public Product(string productId) : base()
    {
        ProductId = productId;
    }
}

[JsonExtensionData] 属性导致字典属性在序列化和反序列化时作为父对象的一部分包含在内。

注意事项:

  • 如果建议的替代方案 Not Acceptable ,您将需要编写自定义 JsonConverter 手动序列化您的 Product 的 .NET 属性以及键和值词典。

  • 正在添加 [JsonInclude]ProductId不会强制它序列化。根据docs for JsonInclude , 当应用于属性时,[它] 表示非公共(public) getter 和 setter 可用于序列化和反序列化。 因此它与此处无关 ProductId已经有公共(public) getter 和 setter。

  • Newtonsoft 也有一个 JsonExtensionData 属性(做同样的事情)。如果您同时使用这两种序列化程序,请小心使用正确的属性。

  • 在您的问题中,您声明不关心反序列化,但反序列化确实可以与 JsonExtensionData 一起正常工作.

演示 fiddle here .

关于c# - 使用 System.Text.Json 的自定义类型继承 Dictionary 的序列化不会序列化其他属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69201788/

相关文章:

java - 带有字符串数组 toString() 输出的 JSONObjcet 具有整数值而不是字符串

java - 我如何用对象反序列化 Map

c# - 页面索引更改问题

javascript - $http 进入 Angular Js

java - 如何使用Java High Level Rest Client API映射elasticsearch查询的结果集?

json - 使用 JSON.Net 的 C# 到 JSON 序列化

c# - 你怎么能在网页中编辑有效的 XML?

c# - 整个类型的 Json.NET 条件序列化

c# - 如何确定哪个用户控件正在调用命令

C# MySQLBulkLoader 覆盖时间戳