JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.73k stars 3.25k forks source link

JsonConvert.DeserializeObject using $type does not (at least for the root object) not use the converter #2977

Open epflbutza opened 1 month ago

epflbutza commented 1 month ago

Same issue like here: https://stackoverflow.com/questions/50374760/why-does-jsonconvert-deserializeobject-not-use-the-specified-jsonconverter

Expected behavior

JsonConverter is executed for the root object too,

Actual behavior

Currently the JsonConverter is executed for a sub object but not for the root object. A quick fix is first to search the $type with a regex and create the type and use this type with the DeserializeObject method.

Steps to reproduce

Define a custom binder to set the $type token. Add a custom JsonConverter Execute DeserializeObject with a json string, without defining the type.

elgonzo commented 1 month ago

FYI: It's not related to root object vs. sub-object per se. This essentially happens when Newtonsoft.Json doesn't know the target type and queries the serialization binder for the target type. After which it doesn't consider json converters for the respective object anymore.

(In your case, the sub object happens to use the converter because the property/field holding the sub object is accordingly typed. If for example you were to make the property/field for the sub object of type object instead, then Newtonsoft.Json would need to query the serialization binder also for the sub object and then also not use the json converter for the sub object.)

Please note that i am not the author/maintainer of Newtonsoft.Json and not associated with the project in any form (i am just a -mostly former- user of Newtonsoft.Json). If you check the commit history as well as the activity of the author of this library here in the Github repo, you will notice that the library basically is legacy and in what i would call "maintenance mode". Due to this, in my honest opinion i would not expect this behavior of Newtonsoft.Json going to be improved, unfortunately.

epflbutza commented 1 month ago

But for the sub objects it is called and for all system types. The fix for me would be, after asking the binder for the type call the converters. Somehow it does it but not for the first one. Working with binders is the advantage not to know what it is insider before using DeserializeObject.

elgonzo commented 1 month ago

But for the sub objects it is called [...]

Somehow it does it but not for the first one.

Read my previous comment again re the property/field holding the sub object.

The fix for me would be [...]

As i mentioned in the last paragraph of my previous comment, look at the development activities regarding this library in the last few years. You should then be able to make your own guesstimate about when such a fix could possibly arrive. Note that i am not arguing that you don't have a valid problem. I am trying to argue that if you are choosing to stick with Newtonsoft.Json, then in all likelihood you will have to live with it and have to keep relying on workarounds (such as with the regex, for example), unfortunately.