对键值对进行序列化和反序列化时,使用“PropertyNamingPolicy”、“PropertyNameCaseInsensitive”和“Encoder”选项

现在,在序列化 KeyValuePair<TKey,TValue> 实例的 KeyValue 属性名称时,JsonSerializer 将使用 PropertyNamingPolicyEncoder 选项。 此外,在反序列化 KeyValuePair<TKey,TValue> 实例时,JsonSerializer 将使用 PropertyNamingPolicyPropertyNameCaseInsensitive 选项。

更改描述

序列化

在 .NET Core 3.x 版本和 System.Text.Json NuGet 包的 4.6.0 - 4.7.2 版本中,KeyValuePair<TKey,TValue> 实例的属性始终准确序列化为“Key”和“Value”,而不考虑任何 JsonSerializerOptions.PropertyNamingPolicyJsonSerializerOptions.Encoder 选项。 下面的代码示例演示在序列化后 KeyValue 属性如何不采用 camel 大小写,即使指定的属性命名策略要求这样做也是如此。

var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
KeyValuePair<int, int> kvp = KeyValuePair.Create(1, 1);
Console.WriteLine(JsonSerializer.Serialize(kvp, options));
// Expected: {"key":1,"value":1}
// Actual: {"Key":1,"Value":1}

从 .NET 5 开始,序列化 KeyValuePair<TKey,TValue> 实例时,将使用 PropertyNamingPolicyEncoder 选项。 下面的代码示例演示在序列化后 KeyValue 属性如何按照指定的属性命名策略采用 camel 大小写。

var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
KeyValuePair<int, int> kvp = KeyValuePair.Create(1, 1);
Console.WriteLine(JsonSerializer.Serialize(kvp, options));
// {"key":1,"value":1}

反序列化

在 .NET Core 3.x 版本和 System.Text.Json NuGet 包的 4.7.x 版本中,如果 JSON 属性名称不精确地表示为 KeyValue(例如,它们不以大写字母开头),则会引发 JsonException。 即使指定的属性命名策略明确允许该操作,也会引发该异常。

var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string json = @"{""key"":1,""value"":1}";
// Throws JsonException.
JsonSerializer.Deserialize<KeyValuePair<int, int>>(json, options);

从 .NET 5 开始,使用 JsonSerializer 进行反序列化时,将使用 PropertyNamingPolicyPropertyNameCaseInsensitive 选项。 例如,下面的代码片段演示了小写的 KeyValue 属性名称的成功反序列化,因为指定的属性命名策略允许这样做。

var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string json = @"{""key"":1,""value"":1}";

KeyValuePair<int, int> kvp = JsonSerializer.Deserialize<KeyValuePair<int, int>>(json);
Console.WriteLine(kvp.Key); // 1
Console.WriteLine(kvp.Value); // 1

为了适应在以前版本中序列化的有效负载,“Key”和“Value”采用特殊大小写,以在反序列化时匹配。 即使 KeyValue 属性名称未根据以下代码示例中的 PropertyNamingPolicy 选项采用 camel 大小写,它们也会成功进行反序列化。

var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string json = @"{""Key"":1,""Value"":1}";

KeyValuePair<int, int> kvp = JsonSerializer.Deserialize<KeyValuePair<int, int>>(json);
Console.WriteLine(kvp.Key); // 1
Console.WriteLine(kvp.Value); // 1

引入的版本

5.0

更改原因

大量客户反馈表明应使用 PropertyNamingPolicy。 出于完整性考虑,还使用了 PropertyNameCaseInsensitiveEncoder 选项,使 KeyValuePair<TKey,TValue> 实例与任何其他普通旧 CLR 对象 (POCO) 得到相同的处理。

如果此更改对你造成干扰,则可以使用自定义转换器来实现所需语义。

受影响的 API