Skip to content
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

Merged
merged 4 commits into from
May 15, 2020

Conversation

layomia
Copy link
Contributor

@layomia layomia commented May 14, 2020

  • 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)

@layomia layomia added area-System.Text.Json breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. labels May 14, 2020
@layomia layomia added this to the 5.0 milestone May 14, 2020
@layomia layomia self-assigned this May 14, 2020
@layomia
Copy link
Contributor Author

layomia commented May 14, 2020

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

// _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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

@steveharter steveharter left a 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>
Copy link
Member

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..

Copy link
Contributor Author

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);
Copy link
Member

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?

Copy link
Contributor Author

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.

[InlineData(@"{""Value"":1,""Value"":2}")]
public static void InvalidJsonFail(string json)
{
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<KeyValuePair<int, int>>(json));
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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
Copy link
Contributor Author

layomia commented May 15, 2020

Will address @jozkee's feedback in a follow up to fix #32148.

@layomia layomia merged commit 8dbfb8e into dotnet:master May 15, 2020
@danmoseley
Copy link
Member

danmoseley commented Jul 24, 2020

@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

@danmoseley danmoseley added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jul 30, 2020
@layomia
Copy link
Contributor Author

layomia commented Oct 3, 2020

Breaking change doc filed: dotnet/docs#20898.

@layomia layomia removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Oct 3, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 9, 2020
@layomia layomia deleted the kvp_policy branch May 1, 2021 00:48
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

KeyValuePair is not properly serialized with JsonNamingPolicy.CamelCase - System.Text.Json
4 participants