Do not prematurely set Converter for Reader/Writer if CanRead/CanWrite is false #2692
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue:
Overlapping converters are overridden, even when one of the converters isn't applicable (via CanRead/CanWrite).
Real World Scenario:
My team has a custom JsonConverter that gets applied dynamically to properties via a ContractResolver, based on which api version the request/response is and if the property is "nullable" (as defined by Microsoft's Azure Resource Manager: x-nullable). This converter acts as a validator of sorts, returning 4xx when an explicit null (
"foo": null
) is present on a non-nullable property. As such, this converter should have CanWrite set to false. However, other converters - namely a StringEnumConverter derivative we use - no longer get applied to properties who have this custom JsonConverter dynamically applied to them.Root Cause:
The issue is that the JsonSerializerInternalReader and JsonSerializerInternalWriter converter-choosing-logic takes the first non-null converter, without checking if that converter CanRead or CanWrite (respectively). If a non-null converter isn't applicable to that Reader or Writer, then it shouldn't be taken.
Workaround:
My team isn't completely blocked without this PR. A workaround that works for us is to leave the customer converter's CanWrite to true but then invoke the serializer's Serialize function: