-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Why does System.Text.Json throw an exception when deserializing polymorphic types in case $type is not the first property #96088
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsI have noticed some behavior that got me surprised. I have an abstract BaseClass and a DerivedClass. [JsonPolymorphic]
[JsonDerivedType(typeof(DerivedClass), "derived")]
public abstract class BaseClass
{
public BaseClass() { }
}
public class DerivedClass : BaseClass
{
public string? Whatever { get; set; }
} And now I have two JSON strings: the first JSON has the type discriminator ( var jsonWorks = "{\"$type\": \"derived\", \"whatever\": \"Bar\"}";
var jsonBreaks = "{\"whatever\": \"Bar\", \"$type\": \"derived\"}";
var obj1 = JsonSerializer.Deserialize<BaseClass>(jsonWorks);
var obj2 = JsonSerializer.Deserialize<BaseClass>(jsonBreaks); // This one will throw an exception The exception that is thrown is of type
It also has an inner exception:
At first glance I thought this would be a bug until someone pointed out this particular area in the documentation.
Since on the top level of any JSON string, you can't really have duplicate properties (e.g the property For anyone interested, I came across this while I was trying to map a property to Image taken from within the database in Datagrip: builder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnType("jsonb")
.HasConversion(
metadata => DatabaseJsonConverter.Serialize(metadata),
json => DatabaseJsonConverter.Deserialize<Metadata>(json)
);
|
See this comment and the comment(s) it refers to: #72604 (comment) |
Closing as duplicate of #72604 |
I have noticed some behavior that got me surprised. I have an abstract BaseClass and a DerivedClass.
And now I have two JSON strings: the first JSON has the type discriminator (
$type
) as the very first property within the JSON - the second JSON string does not. When I performJsonSerializer.Deserialize<BaseClass>()
, an exception is thrown on the second JSON string.The exception that is thrown is of type
System.NotSupportedException
with the following message:It also has an inner exception:
At first glance I thought this would be a bug until someone pointed out this particular area in the documentation.
Since on the top level of any JSON string, you can't really have duplicate properties (e.g the property
username
cannot really appear twice on the same level within a JSON), why isSystem.Text.Json
designed in such a way to throw this exception?For anyone interested, I came across this while I was trying to map a property to
jsonb
using EntityFrameworkCore and within Npgsql. I did have to wrap the JsonSerializer methods into a new class which for the sake of example is calledDatabaseJsonConverter
below. Also, during the "serialization" part of an object, the$type
does get written as the first property within the resulting JSON, but for some reason, after it's saved, the order of properties in my PostgreSQL instance is not the same it was in themetadata => DatabaseJsonConverter.Serialize(metadata)
resulting string.Image taken from within the database in Datagrip:

The text was updated successfully, but these errors were encountered: