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

Document known issues and semantic differences between the various JSON-serialization programming models #26040

Closed
Tracked by #24212
layomia opened this issue Sep 10, 2021 · 2 comments · Fixed by #26559
Assignees
Labels
doc-idea Indicates issues that are suggestions for new topics [org][type][category] Pri3

Comments

@layomia
Copy link
Contributor

layomia commented Sep 10, 2021

Help us make content visible

Describe the new article

With the new JSON source generator, we now have a few programming models for JSON (de)serialization:

  • (De)serialization based on runtime reflection
  • (De)serialization based on compile-time type metadata gathering (metadata source gen mode)
  • Optimized serialization using Utf8JsonWriter directly

We should describe any feature and semantic differences between them, e.g. source-gen lack of support for init-only property deserialization (dotnet/runtime#58770), lack of support for private members.

We should also describe feature differences in fast-path mode vs metadata serialization mode - dotnet/runtime#51945 (comment).


cc @eiriktsarpalis, @steveharter, @tdykstra , @eerhardt, @ericstj, @jeffhandley, @jkotas, @stephentoub

@layomia layomia self-assigned this Sep 10, 2021
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Sep 10, 2021
@layomia
Copy link
Contributor Author

layomia commented Sep 22, 2021

We should also describe feature differences in fast-path mode vs metadata serialization mode - dotnet/runtime#51945 (comment).

This is covered by this section: https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation?pivots=dotnet-6-0#serialization-optimization-mode

We should describe any feature and semantic differences between them

Accessible surface area

The source generator can only access public and internal surface area (ctors, props, fields) on types, while the reflection serializer can access all members with runtime reflection.

Constructors

In both src-gen & reflection mode, only public ctors can be used for deserialization.

Properties

In both src-gen & reflection mode, only public properties can be used for deserialization. However, in reflection mode, [JsonInclude] can be used to support non-public accessors for public properties, e.g a private setter, or an internal getter. In src-gen mode only public/internal accessors are supported, and any attempt to include non-public accessors with [JsonInclude] will lead to a runtime NotSupportedException being thrown.

Fields

Only public fields are supported in both src-gen and reflection implementations.

--

Note that there's a tracking issue for extending non-public support in STJ, but src-gen restrictions would still apply - dotnet/runtime#31511.

Support for deserializing init-only properties

Init-only prop deserialization is supported in the reflection serializer, but not source-gen. This is because the metadata-only mode required for deserialization cannot express the required initialization statically in source, while the reflection serializer can use runtime-reflection to set the properties after construction.

With a new generation mode where read logic is generated using the reader directly (fast-path deserialization), the required static initialization can be provided.

Known issues

https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator

@adegeo adegeo added doc-idea Indicates issues that are suggestions for new topics [org][type][category] and removed ⌚ Not Triaged Not triaged labels Sep 23, 2021
@layomia
Copy link
Contributor Author

layomia commented Oct 12, 2021

From @krwq in dotnet/runtime#60178:

Currently JSON serializer has 3 code paths which are distinct implementations:

  • regular path
  • fast path
  • code gen

we're finding more and more issues related to divergence in behavior.

I think it would be useful to spec out the expected behavior and define how it should work. We should also research other similar specs and existing implementations before finalizing it.

Benefits:

  • source of truth for behavior
  • possible interop with different languages
  • easier to find potential gaps and improvements
  • good place to add security considerations and notes to prevent us from accidentally going into the path of BinaryFormatter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-idea Indicates issues that are suggestions for new topics [org][type][category] Pri3
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants