I am getting some data from an api that returns an object that has a property of Type
Dictionary<int, double?>?
in JSON. The issue is that some times the JSON will pass back Infinity
in the double
property so my deserialize fails trying to convert Infinity
to double
. I am trying to write a JsonConverter
to handle this but I dont know how to check if the double
is Infinity
. This is what I have so far.
internal class InfinityDictionaryToNullJsonConverter : JsonConverter<Dictionary<int, double?>?>
{
public override Dictionary<int, double?>? Read(ref Utf8JsonReader reader, Type typeToConvert,JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject)
{
Type keyType = typeToConvert.GetGenericArguments()[0];
Type valueType = typeToConvert.GetGenericArguments()[1];
if (reader.GetString().Contains("Infinity"))
{
return new Dictionary<int, double?> { { 0, 0 } };
}
}
else
{
var test = reader.GetString();
}
return new Dictionary<int, double?> { { 0, 0 } };
}
public override void Write(Utf8JsonWriter writer,Dictionary<int, double?>? value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
I can see that the reader.TokenType
is JsonTokenType.StartObject
but the next step is what I need help with. I would like to check if the double
is Infinity
, and if it is set it to default(double?)
or even just 0.
An example of the data is here:
{
"TeamRanks": {
"0": "Infinity",
"1": "1757.739122974623"
}
}
3
Answers
the easiest way is
You can directly parse "Infinity, -Infinity, Nan" to double using the following overload of parse:
There is no need for a converter. You may deserialize that JSON by setting
NumberHandling
toJsonNumberHandling.AllowNamedFloatingPointLiterals
andJsonNumberHandling.AllowReadingFromString
:As explained in the docs, this flag has the following possible values:
If you would prefer to replace the
Infinity
values withnull
you could do that in anIJsonOnDeserialized
callback:However,
Double.PositiveInfinity
is a perfectly valid value for a c#double
that can be checked for directly or by using!Double.IsFinite(value)
so you might just leave the values as-is.Demo fiddle here.