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

System.Text.Json serializes both parent and child properties when using inheritance, even when new or override is used in the child class. #108890

Closed
sakitA opened this issue Oct 15, 2024 · 4 comments

Comments

@sakitA
Copy link

sakitA commented Oct 15, 2024

Description

When serializing a class that inherits from an abstract or virtual base class using System.Text.Json, both the properties from the parent class and the child class are serialized, even when the child class overrides or hides the parent properties using the new or override keywords. This behavior leads to duplicate entries for the same property in the serialized JSON output, which is undesirable and unexpected.

Example Code:

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

public abstract class Parent
{
    public string Name { get; set; }

    public int Age { get; set; }
}

public class Child : Parent
{
    [JsonPropertyName("full_name")]
    public new string Name { get; set; } // Hides the parent property

    [JsonPropertyName("child_age")]
    public override int Age { get; set; } // Overrides the parent property
}

class Program
{
    static void Main(string[] args)
    {
        Child child = new Child
        {
            Name = "John Doe",
            Age = 10
        };

        var options = new JsonSerializerOptions
        {
            WriteIndented = true
        };

        string json = JsonSerializer.Serialize(child, options);
        Console.WriteLine(json);
    }
}

Reproduction Steps

Steps to Reproduce:

  1. Create an abstract base class (Parent) with properties.
  2. Create a child class (Child) that inherits from the base class and either:
    • Uses the new keyword to hide the base class properties.
    • Uses the override keyword to override base class properties.
  3. Apply the [JsonPropertyName] attribute to the properties in the child class to customize their names in the JSON output.
  4. Serialize an instance of the Child class using System.Text.Json.

Expected behavior

Only the properties from the child class should be serialized, with the custom names provided by the [JsonPropertyName] attribute. The parent properties should not be serialized if they are hidden or overridden by the child class.

Expected JSON output:

{
  "full_name": "John Doe",  // Only the child property should be serialized
  "child_age": 10           // Only the child property should be serialized
}

Actual behavior

The JSON output contains both the parent and child properties, leading to duplication:

{
  "full_name": "John Doe",  // From child class (expected)
  "Name": "John Doe",       // From parent class (unexpected)
  "child_age": 10,          // From child class (expected)
  "Age": 10                 // From parent class (unexpected)
}

Regression?

No response

Known Workarounds

No response

Configuration

Using .NET8 on Windows 11

Other information

It is simple app, but in our case we want to use JsonPropertyName to rename our properties during the serialization. But because of back compatibility we can't touch or ignore parent properties, that is why we trying to override the properties in new version child class so both can work at the same time.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Oct 15, 2024
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.

@gregsdennis
Copy link
Contributor

gregsdennis commented Oct 16, 2024

I think the current behavior of serializing all properties is generally expected. This is the purpose of using inheritance on models.

I suggest having separate serialization models that make your property names what you want them, then have a mapper between the models.

@sakitA
Copy link
Author

sakitA commented Oct 16, 2024

Having difference property understandable, but why override properties duplicate? Without using jsonpropertyname there is no duplicate because both has the same key name. Json property name cause having different name and serialization use both name and duplicate the property with different name. And I don't think this expected behavior.

@eiriktsarpalis
Copy link
Member

Duplicate of #51165.

@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants