JsonSerializer现在在序列化PropertyNamingPolicy实例的Encoder和Key属性名称时遵循Value和KeyValuePair<TKey,TValue>选项。 此外,在反序列化 JsonSerializer 实例时,PropertyNamingPolicy 将使用 PropertyNameCaseInsensitive 和 KeyValuePair<TKey,TValue> 选项。
更改描述
序列化
在 .NET Core 3.x 版本和 System.Text.Json NuGet 包的 4.6.0-4.7.2 版本中,实例的属性 KeyValuePair<TKey,TValue> 始终完全序列化为“密钥”和“值”,而不考虑任何 JsonSerializerOptions.PropertyNamingPolicy 和 JsonSerializerOptions.Encoder 选项。 下面的代码示例演示在序列化后 Key 和 Value 属性如何不采用 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 开始,序列化PropertyNamingPolicy实例时将遵循Encoder和KeyValuePair<TKey,TValue>选项。 下面的代码示例演示在序列化后 Key 和 Value 属性如何按照指定的属性命名策略采用 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 属性名称不精确地表示为 JsonException 和 Key
(例如,它们不以大写字母开头),则会引发 Value
。 即使指定的属性命名策略明确允许该操作,也会引发该异常。
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string json = @"{""key"":1,""value"":1}";
// Throws JsonException.
JsonSerializer.Deserialize<KeyValuePair<int, int>>(json, options);
从 .NET 5 开始,使用 PropertyNamingPolicy 进行反序列化时,将使用 PropertyNameCaseInsensitive 和 JsonSerializer 选项。 例如,以下代码片段演示了小写 Key 和 Value 属性名称的成功反序列化,因为所指定的属性命名策略允许这种情况。
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”采用特殊大小写,以在反序列化时匹配。 即使 Key 和 Value 属性名称未根据以下代码示例中的 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。 为了完整性,PropertyNameCaseInsensitive 和 Encoder 选项也被接受,因此 KeyValuePair<TKey,TValue> 实例将与任何其他普通的 CLR 对象(POCO)相同地处理。
建议的措施
如果此更改对你造成干扰,则可以使用实现所需语义的 自定义转换器 。