I am using the new .NET serialization classes from System.Text.Json to deserialize a JSON response from a restful endpoint. The structure of the response is:
public class RemoteCallResultDto
{
public bool Succeeded { get; set; }
public string Message { get; set; }
}
public class RemoteCallResultDto<T> : RemoteCallResultDto
{
public T Payload { get; set; }
}
The generic type is what i want to deserialize. The Payload could be a primitive or a class. So i created a custom converter as outlined here.
My converter is as follows:
public class RemoteCallResultDtoTConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsGenericType &&
typeToConvert.GetGenericTypeDefinition() == typeof(RemoteCallResultDto<>);
}
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
{
Type valueType = type.GetGenericArguments()[0];
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
typeof(RemoteCallResultDtoConverterInner<>).MakeGenericType(
new Type[] { valueType }),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: new object[] { options },
culture: null);
return converter;
}
private class RemoteCallResultDtoConverterInner<TPayloadType> : JsonConverter<RemoteCallResultDto<TPayloadType>>
{
private readonly JsonConverter<TPayloadType> _valueConverter;
public RemoteCallResultDtoConverterInner(JsonSerializerOptions options)
{
// For performance, use the existing converter if available.
_valueConverter = (JsonConverter<TPayloadType>)options
.GetConverter(typeof(TPayloadType));
}
public override RemoteCallResultDto<TPayloadType> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (_valueConverter != null)
return new RemoteCallResultDto<TPayloadType> { Payload = _valueConverter.Read(ref reader, typeToConvert, options) };
else
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, RemoteCallResultDto<TPayloadType> value, JsonSerializerOptions options)
{
if (_valueConverter != null)
_valueConverter.Write(writer, value.Payload, options);
else
throw new JsonException();
}
}
}
My problem is that the _valueConverter in the RemoteCallResultDtoConverterInner constructor is always null. This is how i attempt to do the deserialization:
var serializerOptions = new JsonSerializerOptions();
serializerOptions.Converters.Add(new RemoteCallResultDtoTConverter());
RemoteCallResultDto<K> res = JsonSerializer.Deserialize<RemoteCallResultDto<K>>(response, serializerOptions);
Where the response is valid JSON of the form:
{"payload":{"email":"arlvinm@yahoo.com","firstName":"Arlvin","lastName":"Moyo","organization":"Aquants","permissions":["User management - View","Lookup data - View"]},"succeeded":true,"message":null}
Where am i going wrong?