Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Json.Deserialize with Object with Child class with interfaces

Tags:

json

c#

I have some objects:

public class MyObject
{
    public MyField Field { get; set; }
}

public class MyField
{
    [JsonProperty]
    public Entity MyEntity { get; set; }
    public IEntity IMyEntity { get; set; }
}

public interface IEntity
{
    string MyStr { get; }
}

public class Entity : IEntity
{
}

Then I am trying to do something like

JsonConvert.DeserializeObject<MyObject>(myObjStr); 

Which throws an error similar to

Could not create an instance of type MyObject... Type is an interface or abstract class and cannot be instantiated. Path 'MyField.IMyEntity.MyInt'

I can't change the field or entity, as that is in another group's codebase. The MyObject class is in mine. Is there a way to deserialize this object? I've tried a few things with JsonSerializerSettings here JSON.NET - how to deserialize collection of interface-instances? but to no avail.

like image 417
justindao Avatar asked Oct 18 '22 07:10

justindao


1 Answers

You can create your own JSON converter which allows you to specify type mapping:

public class JsonTypeMapper<TFromType, TToType> : JsonConverter
{
    public override bool CanConvert(Type objectType) => objectType == typeof(TFromType);

    public override object ReadJson(JsonReader reader,
     Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize<TToType>(reader);
    }

    public override void WriteJson(JsonWriter writer,
        object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

Then you deserialize like this:

JsonConvert.DeserializeObject<MyObject>(myObjStr, new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new JsonTypeMapper<IEntity, Entity>() }
                                                            //^^^^^^^, ^^^^^^
}); 
like image 130
Rob Avatar answered Oct 21 '22 06:10

Rob