Description
EDIT see #29937 (comment) for the finalized API proposal.
Original proposal by @steveharter (click to view)
Current behavior
Consider a simple model:
abstract class Person {...}
class Customer : Person {...}
The current behavior, by design, is to use the static type and not serialize polymorphically.
// This will serialize all properties on `Person` but not `Customer`:
Person person = new Customer();
string str = JsonSerializer.ToString<Person>(person);
// This does the same thing through generic type inference:
string str = JsonSerializer.ToString(person);
However, if the type is declared to be System.Object
then all properties will be serialized:
object person = new Customer();
// This will serialize all properties on `Customer`
string str = JsonSerializer.ToString(person);
In addition, the Type
parameter can be specified:
Person person = new Customer();
// This will serialize all properties on `Customer`
string str = JsonSerializer.ToString(person, person.GetType());
All of these semantics are current as will remain as-is.
Proposed API
Add an opt-in setting that will serialize all types polymorphically, instead of just System.Object
:
namespace System.Text.Json
{
public class JsonSerializerOptions // existing class
{
. . .
bool SerializePolymorphically { get; set; }
. . .
}
}
Example of new behavior:
var options = new JsonSerializerOptions();
options.SerializePolymorphically = true;
// This will serialize all properties on `Customer`:
Person person = new Customer();
string str = JsonSerializer.ToString(person, options);
This new behavior applies both to the root object being serialized (as shown above) plus any properties on POCOs including collections, such as List<Person>
.
Note: this issue does not enable any additional support for polymorphic deserialize. Currently, a property or collection of type System.Object
will result in a JsonElement
being created. Any additional polymorphic deserialize support must be done with a custom converter.