RicoSuter / NJsonSchema

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

Handle $refs in JsonInheritanceConverter #748

Open RicoSuter opened 6 years ago

RicoSuter commented 6 years ago

Original issue: https://github.com/RSuter/NSwag/issues/1479 from @ikaros88:

When generating a client using NSwagStudio, the resulting C# client contains a copy of the JsonInheritanceConverter class to handle discriminator values for polymorphic DTOs. The problem is when the DTOs have circular references, using the $id and $ref system, as JsonInheritanceConverter seems to parse the JObjects before the $ref tokens have been resolved, resulting in errors as the $ref tokens clearly do not contain the discriminator value.

The following lines from ReadJson fail when the jObject only contains a $ref:

var discriminator = Newtonsoft.Json.Linq.Extensions.Value<string>(jObject.GetValue)_discriminator)); var subtype = GetObjectSubtype(objectType, discriminator);

I fixed this in the generated client by inserting if (jObject.ContainsKey("$ref")) { var reference = jObject["$ref"].ToString(); return serializer.ReferenceResolver.ResolveReference(serializer, reference); } just prior to the above lines.

This fix works for my use case, i do not know if it is a general fix though. Is there any chance of fixing this so i do not have to re-insert the code after every Client generator run?

Is there maybe a more sophisticated way of dealing with this problem, e.g. forcing JSON.NET to resolve references before the converter runs?

Greetings

kevinandrewsde commented 6 years ago

Created minimal solution showcasing the problem: https://github.com/ikaros88/RefTest To cause failure start the RefTest Web Api Project, and then run the unit test in in the UnitTests project. Problem is caused by the JsonInheritanceConverter looking for the discriminator "discriminator" in the $ref instead of resolving the reference.

RicoSuter commented 6 years ago

Until this has been fixed, you can overwrite the template:

https://github.com/RSuter/NJsonSchema/blob/master/src/NJsonSchema.CodeGeneration.CSharp/Templates/JsonInheritanceConverter.liquid

https://github.com/RSuter/NSwag/wiki/Templates https://github.com/RSuter/NJsonSchema/wiki/Templates

Peter-Svahn commented 1 year ago

Hi!

I used your proposed check for $ref above by creating a custom, derived JsonInheritanceConverter, and applied the fix in that class. Works fine as far as I can see. Would like this to be fixed in next release.