I tried to deserialize type derived from interface IComponent. Objects in JSON had defined $type correctly. Although this works flawlessly without custom converters, deserialization with custom converters does not work. I tried converter, but it is not called for ComponentA at all, only with IComponent. I also tried to use contract resolver - CreateContract is called for IComponent and then ComponentA, but if I set converter for ComponentA (as in example) it's completely ignored. However it's not ignored for IComponent. I've found the problem with List<IComponent> when none of my custom converters were called.
Does this library support this scenario? If it does not, could we implement it? :wink:
The code that illustrates the problem:
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.IO;
using System.Text;
namespace Playground
{
public class ConverterContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
JsonContract contract = base.CreateContract(objectType);
if (objectType == typeof(ComponentA))
{
// converter is ignored, but custom converter for IComponent is not
contract.Converter = new ComponentAConverter();
}
return contract;
}
}
public interface IComponent { }
public class ComponentA : IComponent { }
public class ComponentAConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(ComponentA) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
class Program
{
const string contentA = @"{ ""$type"": ""Playground.ComponentA, Playground"" }";
static StreamReader CreateStringStream(string content)
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(content));
return new StreamReader(stream);
}
static void Main(string[] args)
{
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
// both don't work
//, Converters = new JsonConverter[] { new ComponentAConverter() }
, ContractResolver = new ConverterContractResolver()
};
var serializer = JsonSerializer.CreateDefault(settings);
// should throw, but it does not
var entity = (IComponent)serializer.Deserialize(CreateStringStream(contentA), typeof(IComponent));
}
}
}
I tried to deserialize type derived from interface
IComponent
. Objects in JSON had defined$type
correctly. Although this works flawlessly without custom converters, deserialization with custom converters does not work. I tried converter, but it is not called forComponentA
at all, only withIComponent
. I also tried to use contract resolver -CreateContract
is called forIComponent
and thenComponentA
, but if I set converter forComponentA
(as in example) it's completely ignored. However it's not ignored forIComponent
. I've found the problem withList<IComponent>
when none of my custom converters were called.Does this library support this scenario? If it does not, could we implement it? :wink:
The code that illustrates the problem:
Version I used: the latest from nuget.