I am receiving a property that could either have null { "some_obj" : null }
, an empty array [] { "some_obj" : [] }
, or an object has is not null with some properties { "some_obj" : 'name' : 'nick' }
as the value. In this context, an empty array should translate to null, so I created this converter.
public class MyConverter<T> : JsonConverter<T>
{
public override T? Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if(reader.TokenType == JsonTokenType.StartArray)
{
return default(T);
}
else if (reader.TokenType == JsonTokenType.StartObject)
{
return JsonSerializer.Deserialize<T>(ref reader, options);
}
else
{
return default(T);
}
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
=> JsonSerializer.Serialize(writer, (T?)value, options);
}
When the data coming in is { "some_obj" : [] }
, the first if statement is true and I get the following the JsonException when returning default(T)
: "The converter {converter} read too much or not enough." Any idea of what I'm doing wrong? When the data is { "some_obj" : null }
or { "some_obj" : 'name' : 'nick' }
, it's working fine.
I'm using the attribute on a type in one my classes
public class SomeClass
{
[JsonConverter(typeof(MyConverter<SomeObj>))]
[JsonPropertyName("some_obj")]
public SomeObj? SomeObj{ get; set; }
}
public class SomeObj
{
[JsonPropertyName("name")]
public string? Name{ get; set; }
}
UPDATE Making sure I ended on JsonTokenType.EndArray was the solution. Thanks Simon for the ticket reference
public override T? Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject)
{
return JsonSerializer.Deserialize<T>(ref reader, options);
}
if (reader.TokenType == JsonTokenType.StartArray)
{
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray)
{
return default(T);
}
}
}
throw new JsonException();
}