RicoSuter / NJsonSchema

JSON Schema reader, generator and validator for .NET
http://NJsonSchema.org
MIT License
1.38k stars 532 forks source link

TypeScriptGenerator - Generated toJSON method conflicts with STJ deserializing behavior #1597

Open Galashek opened 1 year ago

Galashek commented 1 year ago

System.Text.Json when deserializing polymorphic objects expects $discriminator to be at the start of the object (https://github.com/dotnet/runtime/issues/72604).

In actual toJSON method template discriminator and base class properties are added to the JSON-object after the properties of the inheritor class.

Proposal is to change Class.liquid template by moving super.toJSON(data) call to the start of toJSON method:

    {% if HasInheritance and SupportsOverrideKeyword %}override {% endif %}toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
{% if HasInheritance -%}
        super.toJSON(data);
{% endif -%}
{% if HasIndexerProperty -%}
        for (var property in this) {
            if (this.hasOwnProperty(property))
                data[property] = this[property];
        }
{% endif -%}
{% if HasDiscriminator -%}
        data["{{ BaseDiscriminator }}"] = this._discriminator;
{% endif -%}
{% for property in Properties -%}
        {{ property.ConvertToJavaScriptCode | tab }}
{% endfor -%}
        return data;
    }
InspiringCode commented 1 year ago

We have the same problem here! Trying to switch to System.Text.Json but failing to do so because .NET throws an exception.

My suggestion would also have been to move the base-call to the top which would be sense anyways in my opinion (sub class should always override stuff of base classes). Is there any reason not to make this change?