Skip to content

Reconsider the semantics of JsonProperty.ShouldSerialize null values #71964

Closed
@eiriktsarpalis

Description

@eiriktsarpalis

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.

Metadata

Metadata

Labels

area-System.Text.JsonenhancementProduct code improvement that does NOT require public API changes/additions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions