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

Serialization of abstract properties #65662

Closed
zryska opened this issue Feb 21, 2022 · 2 comments
Closed

Serialization of abstract properties #65662

zryska opened this issue Feb 21, 2022 · 2 comments
Labels
area-System.Text.Json untriaged New issue has not been triaged by the area owner

Comments

@zryska
Copy link

zryska commented Feb 21, 2022

Description

Serialization behavior changed from System.Text.Json version 5.0.0 forward where overridden properties defined with JsonPropertyName decoration are both included in the resulting JSON payload (Id as well as OverridenId for example). We have seen performance degradation when upgrading to .NET 6 and after some investigation identified that the new serialization behavior is the root cause.

Object serialized with System.Text.Json version 4.7.2:

{"CarId":"ecfb9972-4cb9-41be-bbcc-2cfa1539314a","Name":"name","Description":"description"}

The same object serialized with System.Text.Json version 5.0.0

{"CarId":"9c77798e-402f-455b-abc6-49bd4dfa8d26","Id":"9c77798e-402f-455b-abc6-49bd4dfa8d26","Name":"name","Description":"description"}

Reproduction Steps

Define simple base class:

public abstract class ItemBase
{
    public abstract string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

Define specific class and inherit the base class and change property name

public class Car : ItemBase
{
    [JsonPropertyName("CarId")]
    public override string Id { get; set; }
}

Run the example with System.Text.Json version 4.7.2 and upgrade to 5.0.0 or higher afterwards to see different result

static void Main(string[] args)
{
    var car = new Car
    {
        Id = Guid.NewGuid().ToString(),
        Name = "name",
        Description = "description",
    };

    var serializedBytes = JsonSerializer.SerializeToUtf8Bytes(car);

    Console.WriteLine(Encoding.UTF8.GetString(serializedBytes));
}

Repository with repro project: https://github.com/zryska/serialization-repro

Expected behavior

I would expect the behavior to be the same as for 4.7.2 version of System.Text.Json package - only overridden property is included in the payload.

Actual behavior

Both properties are included in the payload.

Regression?

No response

Known Workarounds

This can be mitigated by including [JsonIgnore] attribute on the base class property that shouldn't be included in the payload.

public abstract class ItemBase
{
    [JsonIgnore]
    public abstract string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

Configuration

No response

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Feb 21, 2022
@ghost
Copy link

ghost commented Feb 21, 2022

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

Issue Details

Description

Serialization behavior changed from System.Text.Json version 5.0.0 forward where overridden properties defined with JsonPropertyName decoration are both included in the resulting JSON payload (Id as well as OverridenId for example). We have seen performance degradation when upgrading to .NET 6 and after some investigation identified that the new serialization behavior is the root cause.

Object serialized with System.Text.Json version 4.7.2:

{"CarId":"ecfb9972-4cb9-41be-bbcc-2cfa1539314a","Name":"name","Description":"description"}

The same object serialized with System.Text.Json version 5.0.0

{"CarId":"9c77798e-402f-455b-abc6-49bd4dfa8d26","Id":"9c77798e-402f-455b-abc6-49bd4dfa8d26","Name":"name","Description":"description"}

Reproduction Steps

Define simple base class:

public abstract class ItemBase
{
    public abstract string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

Define specific class and inherit the base class and change property name

public class Car : ItemBase
{
    [JsonPropertyName("CarId")]
    public override string Id { get; set; }
}

Run the example with System.Text.Json version 4.7.2 and upgrade to 5.0.0 or higher afterwards to see different result

static void Main(string[] args)
{
    var car = new Car
    {
        Id = Guid.NewGuid().ToString(),
        Name = "name",
        Description = "description",
    };

    var serializedBytes = JsonSerializer.SerializeToUtf8Bytes(car);

    Console.WriteLine(Encoding.UTF8.GetString(serializedBytes));
}

Expected behavior

I would expect the behavior to be the same as for 4.7.2 version of System.Text.Json package - only overridden property is included in the payload.

Actual behavior

Both properties are included in the payload.

Regression?

No response

Known Workarounds

This can be mitigated by including [JsonIgnore] attribute on the base class property that shouldn't be included in the payload.

public abstract class ItemBase
{
    [JsonIgnore]
    public abstract string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

Configuration

No response

Other information

No response

Author: zryska
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@eiriktsarpalis
Copy link
Member

Duplicate of #51165.

@ghost ghost locked as resolved and limited conversation to collaborators Mar 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

2 participants