docs
docs copied to clipboard
System.Text.Json SourceGenerator should have better docs and public API
(I apologize in advance if this is the wrong place for such kind of feedback. If so, would appreciate any advice where to put this)
Docs issue
The following two links are basically the only docs on JSON source generators:
The issue is that they describe one simple class consisting of basic .net types (e. g. integers or bools) that is nowhere near the real-world usage. Web APIs have a lot of DTOs (data transfer objects) which are used in multiple ways in controllers (get, put, etc.) and can be nested.
Here are just a handful of questions that are not answered in docs:
-
Suppose one has dozens (or hundreds) DTOs in Web API. How one should add source gen for them? One context with dozens (hunderds) of attributes for each DTO? Separate contexts? Should I have source gen for all DTOs or only some?
It would be great to see an example with at least 2-3 DTOs, not a single
WeatherForecast
. And guidelines/tips how to add source generation for the entire API with dozens (hundreds) of DTOs. -
What to do with nested DTOs. E. g.
AddressDto
insidePersonDto
. How to configure source gen for that case? What would happen if nested DTO doesn’t have source gen but a parent does? What would happen if parent DTO has source gen, but nested doesn’t? What if I have a DTO that has 3 nested levels:CompanyDto
that hasEmployeeDto[]
where each one hasAddressDto
, and source gen is configured only forCompanyDto
andAddressDto
? -
How one should handle collections of different types? What types of collections should be marked for source generation? Suppose I have these 3 cases:
- nested
IReadOnlyCollection<AddressDto> Addresses
property insidePersonDto
; - some controller to GET addresses that returns
ActionResult<IEnumerable<AddressDto>>
; - some controller to POST
AddressDto
.
Should I add to source gen all three:
IReadOnlyCollection<AddressDto>
,IEnumerable<AddressDto>
,AddressDto
? Or if justIEnumerable<AddressDto>
andAddressDto
would suffice? - nested
-
What about controller action return type
Task<ActionResult<IEnumerable<OrderDto>>>
: what should be added in this case for source gen? What if the actual variable that is returned inside the controller isList<OrderDto>
orHashSet<OrderDto>
(while the controller’s action method signature isTask<ActionResult<IEnumerable<OrderDto>>>
) = will theIEnumerable<OrderDto>
mentioned in source-gen suffice? -
Is there any way to know if some cases are missed? E. g. if
OrderDto
is added, butIEnumerable<OrderDto>
is not? To paraphrase, is there any way have some warnings during at least runtime(?) if reflection instead of source gen stuff have been used for (de)serialization in API controllers.
Overall UX thoughts
One would think who would not like to have free performance gains of using JSON source gen in Web APIs. Unfortunately current implementation feels like something one should wait for better times before implementing in their code. Something that was half-baked and rushed as a need for some specific case and that is not ready for actual API projects — too much manual boilerplate and not error-prone. Though I may be proven utterly wrong given more detailed docs/guides emerge.
One could ask for an option to apply JsonSerializable
attributes directly to DTO classes instead of some separate context, or many other things like not having to think about collections (e. g. adding OrderDto would automatically handle cases for IEnumerable<OrderDto>).
Of course, ideal case would be not to think about this at all. One possible solution is to have another source generator or T4 template (akin to Entity Framework DB first) that would automatically generate required “json source generator” boilerplate for all .cs files located inside project DTO folder. Is it really the intended way to manually write hundreds of [JsonSerializable(typeof(insert_every_dto_type_name_here_and_collection_permutation))]
?
Document Details
⚠ Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.
- ID: ee53c3dc-df79-82ef-ce25-3233ff292c55
- Version Independent ID: 558903e9-8173-464e-ff8b-7744419ad7e4
- Content: How to use source generation in System.Text.Json - .NET
- Content Source: docs/standard/serialization/system-text-json/source-generation.md
- Product: dotnet-fundamentals
- GitHub Login: @gewarren
- Microsoft Alias: gewarren