-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Honor PropertyNamingPolicy, PropertyNameCaseInsensitive, & Encoder options when (de)serializing KeyValuePair instances #36424
Conversation
The first commit moves KeyValuePair tests to a dedicated file. I suggest that code review starts from the second commit. |
…tions when (de)serializing KeyValuePair instances
...ystem.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
Outdated
Show resolved
Hide resolved
...ystem.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
Show resolved
Hide resolved
...ystem.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
Show resolved
Hide resolved
...ystem.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
Show resolved
Hide resolved
|
||
// _keyName and _valueName as JsonEncodedText. | ||
private JsonEncodedText _keyNameEncoded; | ||
private JsonEncodedText _valueNameEncoded; | ||
|
||
// todo: https://github.com/dotnet/runtime/issues/32352 | ||
// it is possible to cache the underlying converters since this is an internal converter and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment pertains to looking up the System.String converter and caching that. This is in case someone changes the converter.
IMO we should either fix it in this PR\pass or close the issue for 5.0 if we don't want to forward to the "proper" converter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll prioritize making a PR to close this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than last comment around removing unnecessary Key Value check, LGTM
<data name="SerializerDictionaryKeyNull" xml:space="preserve"> | ||
<value>The dictionary key policy '{0}' cannot return a null key.</value> | ||
<data name="NamingPolicyReturnNull" xml:space="preserve"> | ||
<value>The naming policy '{0}' cannot return null.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include the naming policy in the message for the PropertyNamingPolicy
used on CLR propertiesas well? Right now it says The JSON property name for '{0}.{1}' cannot be null.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we could throw a more specific message (in a clean up PR), although right now it shouldn't be hard for a caller to tell what caused an exception with this message.
|
||
if (_keyName == null || _valueName == null) | ||
{ | ||
ThrowHelper.ThrowInvalidOperationException_NamingPolicyReturnNull(namingPolicy); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider using ThrowInvalidOperationException_SerializerPropertyNameNull
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did. It's achievable with some refactoring. We don't create a JsonPropertyInfo
for the "Key" and "Value" properties, so we'd have to pass the property names by hand.
...ystem.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
Show resolved
Hide resolved
...ystem.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
Show resolved
Hide resolved
...braries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs
Show resolved
Hide resolved
[InlineData(@"{""Value"":1,""Value"":2}")] | ||
public static void InvalidJsonFail(string json) | ||
{ | ||
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<KeyValuePair<int, int>>(json)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the JSON Path correct in these cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't create JsonPropertyInfo
instances for the key and value properties, so JSON path will not point directly to them, but to the property name for the KVP instance.
I think this granularity is good enough, but I'll estimate the effort to get the specific path then create an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep in mind that there is already an issue for general consistency of JSON Path #31955, but sounds like you want to do something scoping only KVP, so maybe make sure to link them.
@layomia this is labeled breaking change. Can you please open an issue with https://github.com/dotnet/docs/issues/new?template=dotnet-breaking-change.md I don't see an existing one |
Breaking change doc filed: dotnet/docs#20898. |
Fixes KeyValuePair is not properly serialized with JsonNamingPolicy.CamelCase - System.Text.Json #1197
This is a breaking change in that we'll potentially serialize the property names differently than in .NET Core 3.x/System.Text.Json 4.7.x (as influenced by the naming policy & encoder). However, roundtripping is not broken as the literals "Key" and "Value" are special-cased to match when deserializing, to accommodate payloads that were serialized with previous versions.
Pushes code coverage for KeyValuePair converter to 100% (previously 70% line, 77% branch)