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.JsonSerializer.Serialize does not correctly serialize classes that inherit from List<T> #79106

Closed
DWAK-ATTK opened this issue Dec 1, 2022 · 6 comments

Comments

@DWAK-ATTK
Copy link

DWAK-ATTK commented Dec 1, 2022

Description

Given a class that inherits from List<T> with additional custom properties, the JsonSerializer only serializes the List data and not the custom properties.

Reproduction Steps

public class Things : List<string> {
    public DateTime BeginTime {get;set;} = DateTime.MinValue;
}


public static void Main() {
    Things things = new Things();
    things.BeginTime = DateTime.Now;
    things.Add("Thing One");
    things.Add("Thing Two");
    string json = JsonSerializer.Serialize(things);

    Console.WriteLine(json);    // where has the BeginTime run off to?    ["Thing One","Thing Two"]
}

Expected behavior

I would expect both the list data and the custom properties to be serialized. (And, of course, deserialized).

Actual behavior

Only the list data is serialized. No custom properties are serialized.

Regression?

I don't know.

Known Workarounds

One could change their class to use encapsulation rather than inheritance, but that may not make sense in any particular instance/architecture. One should not need to worry about whether their class will de/serialize properly when designing their data objects. Serialization is one of those things that are often hidden (say, when using a WebAPI) so where possible serialization should "just work".

Another workaround would be to create a custom serializer (adapter.. whatever its called).. but that seems pretty heavy-handed for something this trivial.

Configuration

.NET 7.0
Windows 10 22H2 x64
I do not believe this to be specific to this configuration, since the same behavior can be observed on dotnetfiddle.
I have not tried this on Blazor, only .NET 7.0 Console.

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 1, 2022
@ghost
Copy link

ghost commented Dec 1, 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

Description

Given a class that inherits from List with additional custom properties, the JsonSerializer only serializes the List data and not the custom properties.

Reproduction Steps

public class Things : List {
public DateTime BeginTime {get;set;} = DateTime.MinValue;
}

public static void Main() {
Things things = new Things();
things.BeginTime = DateTime.Now;
things.Add("Thing One");
things.Add("Thing Two");
string json = JsonSerializer.Serialize(things);

Console.WriteLine(json);    // where has the BeginTime run off to?    ["Thing One","Thing Two"]

}

Expected behavior

I would expect both the list data and the custom properties to be serialized. (And, of course, deserialized).

Actual behavior

Only the list data is serialized. No custom properties are serialized.

Regression?

I don't know.

Known Workarounds

One could change their class to use encapsulation rather than inheritance, but that may not make sense in any particular instance/architecture. One should not need to worry about whether their class will de/serialize properly when designing their data objects. Serialization is one of those things that are often hidden (say, when using a WebAPI) so where possible serialization should "just work".

Another workaround would be to create a custom serializer (adapter.. whatever its called).. but that seems pretty heavy-handed for something this trivial.

Configuration

.NET 7.0
Windows 10 22H2 x64
I do not believe this to be specific to this configuration, since the same behavior can be observed on dotnetfiddle.
I have not tried this on Blazor, only .NET 7.0 Console.

Other information

No response

Author: DWAK-ATTK
Assignees: -
Labels:

area-System.Text.Json

Milestone: -

@pinkfloydx33
Copy link

How do you expect it to serialize? What would the output look like? A list is serialized as a JSON array, they don't have additional properties. So what might it look like if it were supported?

@DWAK-ATTK
Copy link
Author

DWAK-ATTK commented Dec 1, 2022

If you're asking me specifically - I don't know. I'm an end-user with a full-time job and I have other problems to solve. This is something that feels like a bug in the BCL and is for the BCL team to solve.

@pinkfloydx33
Copy link

I'm asking what you expect it to look like when it's serialized. You obviously have something in mind.

I'm not sure how it could be a bug; it's either an object with properties (without the items), or it's a straight array. In json it can't really be both at once which is why it's important to understand what you're expecting it to look like.

Perhaps something like this?

{
    "beginTime": "...",
    "0": "Thing One",
    "1": "Thing Two"
}

Or this?

{
    "beginTime": "...",
    "list": [ "Thing One", "Thing Two" ] 
}

@DWAK-ATTK
Copy link
Author

I would think something along the lines the second example.
"list" isn't going to work because one of the custom properties may be called "list". Perhaps "base.list", or "<>internal.list", or "@list".
Or maybe it is done via an attribute on the class.. something like [JsonArrayLikeObject(PropertyName = "whatever the developer wants")] ...not really sure.. something for the team to work out.

My immediate concern is serializing to/from C# POCOs.. but the BCL team will have to consider interop with other systems as well. So no, I really don't have anything in mind for the json format because my specific use case is using json as a persistence mechanism for storing and reconstituting C# objects. My particular use case where this was discovered is trivial and I can change to encapsulation if I need to... but it doesn't seem like this should be an unsupported scenario.

@eiriktsarpalis
Copy link
Member

System.Text.Json supports serializing types as objects or arrays, but not a mix of both. The current convention is that every type implementing IEnumerable gets serialized as an array of elements and any properties or fields get ignored. We plan to make this more configurable for users via #63791. Mixing and matching is not something we're planning on supporting since, frankly, there is no agreed upon standard on how to do this and any encoding would largely be arbitrary on our side -- you would need to write your own custom converter for that I'm afraid.

@eiriktsarpalis eiriktsarpalis closed this as not planned Won't fix, can't repro, duplicate, stale Dec 2, 2022
@eiriktsarpalis eiriktsarpalis removed the untriaged New issue has not been triaged by the area owner label Dec 2, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jan 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants