-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
SystemTextJsonOutputFormatter calls the serializer with unexpected Type #44852
Comments
Thanks for contacting us. |
I had the same problem and I created a repo/package to solve it. Repo: marcelbarner/AspNetCore.Json.SinglePolymorphicResponse |
This looks incorrect to me, different output depending if I use the Generic form or not: var test = new TestA{ Id="123", Name="TestA"}
var nonGenericCall = JsonSerializer.Serialize(test, test.GetType());
var genericCall = JsonSerializer.Serialize<TestBase>(test);
[JsonDerivedType(typeof(TestBase), typeDiscriminator: nameof(TestBase))]
[JsonDerivedType(typeof(TestA), typeDiscriminator: nameof(TestA))]
public class TestBase
{
public string Id { get; set; }
}
public class TestA : TestBase
{
public string Name { get; set; }
} I get the following: nonGenericCall = "{"id"="123","name"="TestA"}" *** Update *** Looks like my bad, specifying base class as type argument works: |
In my scenario (bi directional polymorphic events using SignalR with .Net client) it is not possible to specify a base class and normally a custom JsonConverter is used to manually add the type discriminators. After further research I found that duplicating the JsonDerivedType attribute on the corresponding Derived class enables the non generic call to JsonSerializer.Serialize to add the type discriminator. This restriction and work around may be worth adding to the Serialize properties of derived classes documentation. var test = new TestA{ Id="123", Name="TestA"}
var nonGenericCall = JsonSerializer.Serialize(test, test.GetType());
var genericCall = JsonSerializer.Serialize<TestBase>(test);
[JsonDerivedType(typeof(TestBase), typeDiscriminator: nameof(TestBase))]
[JsonDerivedType(typeof(TestA), typeDiscriminator: nameof(TestA))]
public class TestBase
{
public string Id { get; set; }
}
[JsonDerivedType(typeof(TestA), typeDiscriminator: nameof(TestA))]
public class TestA : TestBase
{
public string Name { get; set; }
} I now get the desired output as follows: nonGenericCall = "{$type="TestA", "id"="123", "name"="TestA"}" |
cc @dotnet/area-system-text-json |
I don't think this will be necessary once #46008 has been merged, no? |
Exactly, we are adding additional code to fix this behavior in ASP.NET Core. However, I believe the question is about how the Serializer polymorphism work in general, @stephenwelsh is that right? |
I see. @stephenwelsh you might want to check dotnet/runtime#77532 which tracks this issue in the STJ repo, in particular I've included a workaround that lets you achieve the semantics you desire without the need to duplicate any annotations. |
Is there an existing issue for this?
Describe the bug
hi there,
after a short talk with lovely people on runtime team (#dotnet/runtime/issues/77532); i think the issue below needs to be resolved here:
i want to utilize the new json polymorphism features:
what i expect to get is:
{"$type":"TheDerivedType","prop2":2,"prop1":1}
but as discussed in #41399 SystemTextJsonOutputFormatter calls the serializer in a very specific way. this call practically hides all the new metadata from the serializer and produces json without discriminator info. without discriminator, the receiving party fails to deserialize this json.
Expected Behavior
SystemTextJsonOutputFormatter and other json returning types (like JO result etc.) rendering with STJ should respect the polymorphic serialization metadata provided.
current:
{"prop2":2,"prop1":1}
expected:
{"$type":"TheDerivedType","prop2":2,"prop1":1}
Steps To Reproduce
clone the repo and make the get reqs below:
Exceptions (if any)
No response
.NET Version
7.0.100-rc.2.22477.23
Anything else?
No response
The text was updated successfully, but these errors were encountered: