You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
This looks like a duplicate of this issue but I was lead there by my attempt to remove the IConvertible interface...
In essence, none of the UnitsNetBaseJsonConverter we have are ever getting called for a property such as public HowMuch? NullableQuantity { get; set; } ... because it doesn't implement the IConvertible interface 😆 ..
To Reproduce
I took inspiration from this test, and tried to replicate it in the HowMuchTests
Newtonsoft.Json.JsonSerializationException
Unable to find a constructor to use for type UnitsNet.UnitInfo. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'NullableQuantity.QuantityInfo.UnitInfos[0].Value', line 18, position 18.
This is because the nullable property is not being matched against the converter, so the serializedQuantity string contains all public properties and their descendants (not crashing yet), and on the way back- it once again ignores the converter, and attempts to reconstruct everything, and fails (because of the constructors).
And what about the IConvertible - the exact same test passes when we use the internal quantities:
... frankly I'm not sure, but what I know is that as soon as as I removed the IConvertible from the Frequence (and all other quantities), the nullable-struct-property tests started failing in the same fashion. Meanwhile, I know that none of the IConvertible interface members are being called in the original tests- yet there must be something about the interface that is obviously being checked for somewhere..
Puzzled by it, I looked around and found a few open issues that seem to be related...
The suggested workarounds mentioned using the JsonConverter instead of the JsonConverter<T> and overriding the CanConvert such that it handles the Nullable<T> case as well..
So I did (comments omitted for brevity)..
publicabstractclassNullableQuantityConverter<T>:JsonConverter{publicoverrideboolCanConvert(TypeobjectType){// Check if the type directly implements TQuantityif(typeof(T).IsAssignableFrom(objectType)){returntrue;}// Check if the type is a Nullable<T> where T implements IQuantityType?underlyingType=Nullable.GetUnderlyingType(objectType);returnunderlyingType!=null&&typeof(T).IsAssignableFrom(underlyingType);}publicsealedoverridevoidWriteJson(JsonWriterwriter,object?value,JsonSerializerserializer){switch(value){caseTquantity:WriteJson(writer,quantity,serializer);break;casenull:WriteJson(writer,default,serializer);break;default:thrownewJsonSerializationException("Converter cannot write specified value to JSON. An IQuantity is required.");}}publicabstractvoidWriteJson(JsonWriterwriter,T?quantity,JsonSerializerserializer);publicsealedoverrideobject?ReadJson(JsonReaderreader,TypeobjectType,object?existingValue,JsonSerializerserializer){returnexistingValueswitch{TexistingQuantity=>ReadJson(reader,objectType,existingQuantity,true,serializer),null=>ReadJson(reader,objectType,default,false,serializer),
_ =>thrownewJsonSerializationException("Converter cannot read JSON with the specified existing value. An IQuantity is required.")};}publicabstractT?ReadJson(JsonReaderreader,TypeobjectType,T?existingValue,boolhasExistingValue,JsonSerializerserializer);}
After which I simply switched the UnitsNetBaseJsonConverters base class from JsonConverter<T> to the NullableQuantityConverter<T> and all tests are now green (including in the version where Frequence is not IConvertible)...
As it stands, the current issue only affects the nullable external quantities, however if we decide to move away from the IConvertible interface, this issue will really become relevant.
The text was updated successfully, but these errors were encountered:
Describe the bug
This looks like a duplicate of this issue but I was lead there by my attempt to remove the
IConvertible
interface...In essence, none of the
UnitsNetBaseJsonConverter
we have are ever getting called for a property such aspublic HowMuch? NullableQuantity { get; set; }
... because it doesn't implement theIConvertible
interface 😆 ..To Reproduce
I took inspiration from this test, and tried to replicate it in the
HowMuchTests
Here's the new
HowMuchTets.cs
:SerializeObjectWithNullableQuantity
fails. withThis is because the nullable property is not being matched against the converter, so the
serializedQuantity
string contains all public properties and their descendants (not crashing yet), and on the way back- it once again ignores the converter, and attempts to reconstruct everything, and fails (because of the constructors).And what about the
IConvertible
- the exact same test passes when we use the internal quantities:... frankly I'm not sure, but what I know is that as soon as as I removed the
IConvertible
from theFrequence
(and all other quantities), the nullable-struct-property tests started failing in the same fashion. Meanwhile, I know that none of theIConvertible
interface members are being called in the original tests- yet there must be something about the interface that is obviously being checked for somewhere..Puzzled by it, I looked around and found a few open issues that seem to be related...
The suggested workarounds mentioned using the
JsonConverter
instead of theJsonConverter<T>
and overriding theCanConvert
such that it handles theNullable<T>
case as well..So I did (comments omitted for brevity)..
After which I simply switched the
UnitsNetBaseJsonConverter
s base class fromJsonConverter<T>
to theNullableQuantityConverter<T>
and all tests are now green (including in the version whereFrequence
is notIConvertible
)...As it stands, the current issue only affects the nullable external quantities, however if we decide to move away from the
IConvertible
interface, this issue will really become relevant.The text was updated successfully, but these errors were encountered: