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

Reconsider the semantics of JsonProperty.ShouldSerialize null values #71964

Closed
Tracked by #63686
eiriktsarpalis opened this issue Jul 11, 2022 · 3 comments
Closed
Tracked by #63686
Assignees
Labels
area-System.Text.Json enhancement Product code improvement that does NOT require public API changes/additions
Milestone

Comments

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Jul 11, 2022

I'd expect ShouldSerialize = null brings me back default behavior from options and not be equivalent to always serialize.

Originally posted by @krwq in #71908 (comment)

Under the current implementation, a null ShouldSerialize value will result in an ignore policy being determined by either JsonSerializer.DefaultIgnoreCondition or JsonSerializer.IgnoreNullValues settings. This is despite the fact that we are documenting null as meaning "always serialize". While there are merits to the current approach there are a few downsides to be considered as well:

  1. Type-specific configuration should override global configuration. As a user, explicitly setting ShouldSerialize = null; should clearly result in no serializability checks being made. This is similar to how JsonIgnoreAttribute overrides DefaultJsonIgnoreCondition.
  2. As a custom contract resolver author, it is impossible to completely disable ShouldSerialize checks for every JsonSerializerOptions configuration unless I explicitly set a predicate that always returns true. Forcing an additional delegate on an otherwise very common usage scenario is counterintuitive and less efficient.
  3. While a contract resolver does consult JsonSerializerOptions settings when doing its work, the resultant contract is no longer the single source of truth -- the final contract will instead depend on configuration that is non-modifiable by the resolver author.
  4. The current handling of DefaultIgnoreCondition and IgnoreNullValues is inconsistent with how IgnoreReadOnlyProperties and IgnoreReadOnlyFields are treated. The latter group feeds into the contract model and is user-modifiable.

#71908 attempted to change this but it got reverted due to pushback. Nevertheless, I still think we should consider this.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jul 11, 2022
@eiriktsarpalis eiriktsarpalis self-assigned this Jul 11, 2022
@ghost
Copy link

ghost commented Jul 11, 2022

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

I'd expect ShouldSerialize = null brings me back default behavior from options and not be equivalent to always serialize.

Originally posted by @krwq in #71908 (comment)

Under the current implementation, a null ShouldSerialize value will result in an ignore policy being determined by either JsonSerializer.DefaultIgnoreCondition or JsonSerializer.IgnoreNullValues settings. This is despite the fact that we are documenting null as meaning "always serialize". While there are merits to the current approach there are a few downsides to be considered as well:

  1. Type-specific configuration should override global configuration. As a user, explicitly setting ShouldSerialize = null; should clearly result in no serializability checks being made. This is similar to how JsonIgnoreAttribute overrides DefaultJsonIgnoreCondition.
  2. As a custom contract resolver author, it is impossible to completely disable ShouldSerialize checks for every JsonSerializerOptions configuration unless I explicitly set a predicate that always returns true. Forcing an additional delegate on an otherwise very common usage scenario is counterintuitive and less efficient.
  3. While a contract resolver does consult JsonSerializerOptions settings when doing its work, the resultant contract is no longer the single source of truth -- the final contract will instead depend on configuration that is non-modifiable by the resolver author.

#71908 attempted to change this but it got reverted due to pushback. Nevertheless, I still think we should consider this.

Author: eiriktsarpalis
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@eiriktsarpalis eiriktsarpalis added this to the 7.0.0 milestone Jul 11, 2022
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jul 11, 2022
@eiriktsarpalis eiriktsarpalis added the enhancement Product code improvement that does NOT require public API changes/additions label Jul 11, 2022
@krwq
Copy link
Member

krwq commented Jul 12, 2022

See my example here:

#71908 (comment)

also null defaulting to do what options do is more consistent with the rest of the framework (and also seems NSJ) than override default options behavior and always serialize

@eiriktsarpalis
Copy link
Member Author

Given the issue surfaced by #72175 I think we can put this to bed for now. We can re-evaluate in the future.

@ghost ghost locked as resolved and limited conversation to collaborators Aug 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

No branches or pull requests

2 participants