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

Cannot use Properties with $-character when reading System.Text.Json metadata. #79482

Open
1 task done
queequac opened this issue Dec 9, 2022 · 4 comments
Open
1 task done
Labels
area-System.Text.Json enhancement Product code improvement that does NOT require public API changes/additions
Milestone

Comments

@queequac
Copy link

queequac commented Dec 9, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

My json documents contain fields with leading $-character. In general this is no issue, I can add a [JsonProperty("$something")] to the property and it's serialized correctly.

In some cases I need polymorphism. In this case the minimal API is breaking.
While the new JsonPolymorphic feature works as expected by defining some discriminator (which can have a leading $), here any further property using a leading $-character cannot be used.

Sample:


    public class Root
    {
        [JsonPropertyName("$more")]
        public Base More { get; set; }
    }

    [JsonPolymorphic]
    [JsonDerivedType(typeof(A), "a")]
    [JsonDerivedType(typeof(B), "b")]
    public class Base {  }

    public class A : Base
    {
        [JsonPropertyName("$dollar")]
        public string Dollar { get; set; }
    }

    public class B : Base
    {
        [JsonPropertyName("cents")]
        public string Dollar { get; set; }
    }

I am using the following minimal API:

    app.MapPost("/root", (HttpContext context, [FromBody] Root content) =>
    {
       // Do something.
    }).WithName("PostReferences").WithTags("Anchor Core Service");

Deserializing the following works fine:
{ "$more": { "$type": "b", "cents": "foo" }

But this does not:
{ "$more": { "$type": "a", "$dollar": "foo" }
Here the delegate is not even called, but the endpoint returns error 500.

Whenever a property with a leading dollar sign is passed within the polymorophic class, it breaks. On the non polymorphic it is no problem (see Root)

This seems to be related to the fact that dollars are interpreted as metadata and polymorphism is using metadata for the discriminator... I found some JsonSerializerSettings that would allow to mess arround with MetadataPropertyHandling, but seems that's nothing I can set for Minimal API in .NET 7.

Any suggestions how I could still deserialize the document I get passed with dollars in this case?

Expected Behavior

Deserializing should allow dollar signs on polymorphic classes just like on non polymorphic ones.

Steps To Reproduce

No response

Exceptions (if any)

The minimal API returns error code 500 with the following message:

Internal error. System error or malformed request. (Failed to read parameter "Root content" from the request body as JSON.)

.NET Version

7

Anything else?

No response

@queequac
Copy link
Author

queequac commented Dec 9, 2022

Seems to be related to System.Text.Json:
System.Text.Json.JsonException: Properties that start with '$' are not allowed in types that support metadata. Either escape the character or disable reference preservation and polymorphic deserialization.

Turning off polymorphism is not an option, since I cannot solve my issue then... and in case of escaping I am not sure what is meant, but most likely I don't have the dollar then anymore.

@davidfowl davidfowl transferred this issue from dotnet/aspnetcore Dec 10, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 10, 2022
@ghost
Copy link

ghost commented Dec 10, 2022

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

Issue Details

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

My json documents contain fields with leading $-character. In general this is no issue, I can add a [JsonProperty("$something")] to the property and it's serialized correctly.

In some cases I need polymorphism. In this case the minimal API is breaking.
While the new JsonPolymorphic feature works as expected by defining some discriminator (which can have a leading $), here any further property using a leading $-character cannot be used.

Sample:


    public class Root
    {
        [JsonPropertyName("$more")]
        public Base More { get; set; }
    }

    [JsonPolymorphic]
    [JsonDerivedType(typeof(A), "a")]
    [JsonDerivedType(typeof(B), "b")]
    public class Base {  }

    public class A : Base
    {
        [JsonPropertyName("$dollar")]
        public string Dollar { get; set; }
    }

    public class B : Base
    {
        [JsonPropertyName("cents")]
        public string Dollar { get; set; }
    }

I am using the following minimal API:

    app.MapPost("/root", (HttpContext context, [FromBody] Root content) =>
    {
       // Do something.
    }).WithName("PostReferences").WithTags("Anchor Core Service");

Deserializing the following works fine:
{ "$more": { "$type": "b", "cents": "foo" }

But this does not:
{ "$more": { "$type": "a", "$dollar": "foo" }
Here the delegate is not even called, but the endpoint returns error 500.

Whenever a property with a leading dollar sign is passed within the polymorophic class, it breaks. On the non polymorphic it is no problem (see Root)

This seems to be related to the fact that dollars are interpreted as metadata and polymorphism is using metadata for the discriminator... I found some JsonSerializerSettings that would allow to mess arround with MetadataPropertyHandling, but seems that's nothing I can set for Minimal API in .NET 7.

Any suggestions how I could still deserialize the document I get passed with dollars in this case?

Expected Behavior

Deserializing should allow dollar signs on polymorphic classes just like on non polymorphic ones.

Steps To Reproduce

No response

Exceptions (if any)

The minimal API returns error code 500 with the following message:

Internal error. System error or malformed request. (Failed to read parameter "Root content" from the request body as JSON.)

.NET Version

7

Anything else?

No response

Author: queequac
Assignees: -
Labels:

area-System.Text.Json, investigate

Milestone: -

@gregsdennis
Copy link
Contributor

Might be a more general case of #79059

@eiriktsarpalis
Copy link
Member

Yes, this is a by-design restriction of the STJ metadata reader. Further investigation is needed to determine the original motivations and whether they are still valid, but we should definitely look at relaxing this in the future.

@eiriktsarpalis eiriktsarpalis added enhancement Product code improvement that does NOT require public API changes/additions and removed untriaged New issue has not been triaged by the area owner investigate labels Dec 12, 2022
@eiriktsarpalis eiriktsarpalis changed the title [Minimal APIs] Cannot use Properties with $-character with JsonPolymorphism Cannot use Properties with $-character when reading System.Text.Json metadata. Dec 12, 2022
@eiriktsarpalis eiriktsarpalis added this to the Future milestone Dec 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Text.Json enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

No branches or pull requests

4 participants