Skip to content

Conversation

@Maximys
Copy link
Contributor

@Maximys Maximys commented Apr 21, 2025

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Apr 21, 2025
@dotnet-policy-service
Copy link
Contributor

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

using System.Text.Json.Serialization.Metadata.Generics;

namespace System.Text.Json.Nodes
namespace System.Text.Json.Nodes.Generics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid including large refactor without first discussing with the owners. It can have many unintentional effects.


namespace System.Text.Json.Serialization.Converters.Node.Generics
{
internal sealed class JsonValuePrimitiveBooleanConverter : JsonValuePrimitiveConverter<bool>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not efficient to create dedicated converter class for each generic instantiation.

Instead, create a converter factory for Generic<T>, and invokes the converter of T. Check how NullableConverter, FSharpOptionConverter and JsonCollectionConverter invokes JsonConverter<TElement>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the performance of this approach was better

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it may improve performance to inline one level of virtual call, it can be easily compensated by other stuff like the ConcurrentDictionary lookup. It's way not maintainable.

Copy link
Member

@huoyaoyuan huoyaoyuan Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also noticed a behavioral discrepancy. If the caller specifies a converter for primitive type, it will be respected by the "container" converters (collections/nullable), but not JsonObject. Even if we decide to keep this behavior, it should be achieved in generic way, by acquiring corresponding JsonPrimitiveConverter<T>.

I'd suggest to hold off and let the area owner make a decision on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, and this code already removed

return false;
}

internal char GetChar()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes can be reverted once you are invoking the corresponding JsonConverter<Primitive>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed by force push 9047de2

{
private static JsonNodeConverter? s_nodeConverter;
private static JsonArrayConverter? s_arrayConverter;
private static ConcurrentDictionary<Type, JsonConverter>? s_jsonValuePrimitiveConverters;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not store converters like this. Use a converter factory to create converter for each JsonValuePrimitive<T>. Check NullableConverterFactory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed by force push 9047de2

@Maximys Maximys force-pushed the bugfix/113926-fix-invalid-jsonnode-deserialization branch from cf9d968 to 9047de2 Compare April 23, 2025 07:10
Copy link
Member

@eiriktsarpalis eiriktsarpalis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, and apologies for the delay in responding. I would suggest a simpler solution which would involve making JsonValueConverter a generic type with the T : JsonValue. Then you could just insert JsonValueConverter<JsonValuePrimitive> in the list of converters in the resolver.

@eiriktsarpalis eiriktsarpalis added the needs-author-action An issue or pull request that requires more info or actions from the author. label Sep 2, 2025
@dotnet-policy-service
Copy link
Contributor

This pull request has been automatically marked no-recent-activity because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove no-recent-activity.

@dotnet-policy-service
Copy link
Contributor

This pull request will now be closed since it had been marked no-recent-activity but received no further activity in the past 14 days. It is still possible to reopen or comment on the pull request, but please note that it will be locked if it remains inactive for another 30 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Text.Json community-contribution Indicates that the PR has been added by a community member needs-author-action An issue or pull request that requires more info or actions from the author. no-recent-activity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deserialization of a JsonNode with string value fails

3 participants