2016-06-16 2 views
3

У меня есть некоторые объекты:C# Json.Deserialize с помощью объекта с детьми класса с интерфейсами

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 
{ 
} 

Тогда я пытаюсь сделать что-то вроде

JsonConvert.DeserializeObject<MyObject>(myObjStr); 

Который выдает ошибку, аналогичную

Не удалось создать экземпляр типа MyObject ... Тип - это интерфейс или абстрактный класс и не может быть создан. Path 'MyField.IMyEntity.MyInt'

Я не могу изменить поле или сущность, как это находится в кодовой базе другой группы. Класс MyObject принадлежит мне. Есть ли способ десериализовать этот объект? Я пробовал несколько вещей с помощью JsonSerializerSettings здесь JSON.NET - how to deserialize collection of interface-instances?, но безрезультатно.

ответ

1

Вы можете создать свой собственный конвертер JSON, который позволяет указать тип отображения:

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); 
    } 
} 

Тогда вы десериализации, как это:

JsonConvert.DeserializeObject<MyObject>(myObjStr, new JsonSerializerSettings 
{ 
    Converters = new List<JsonConverter> { new JsonTypeMapper<IEntity, Entity>() } 
                  //^^^^^^^, ^^^^^^ 
}); 
+1

Для того, чтобы написать еще проще, вы можете переопределить [ ' CanWrite'] (http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonConverter_CanWrite.htm) и вернуть 'false'. – dbc

+0

@dbc Правильно! Хотя 'WriteJson' на самом деле является абстрактным методом, поэтому нам пришлось бы заменить реализацию с помощью« NotImplementedException »(или аналогичного). Если 'JsonTypeMapper' сам был предназначен для переопределения (или абстрактного), я бы определенно придерживался' CanWrite', но, как вопрос предпочтения, я стараюсь избегать «NotImplementedException». – Rob

Смежные вопросы