2013-04-25 4 views
2

Я использую Entity Framework Code Сначала table-per-hierarchy в моем проекте ASP.NET Web API. Одна из моих моделей имеет список, который относится к типу абстрактного базового класса иерархии.Как JSON.NET сериализует объекты при использовании EF table-per-hierarchy?

List<Dog> // (for example; with GoldenRetriever, BorderCollie, etc inheriting) 

Я пытаюсь протестировать POSTing некоторые данные в свой контроллер API с помощью Fiddler. Но я не знаю, как представлять JSON, когда я это делаю. Если я пытаюсь что-то вроде:

"Dogs": 
[ 
    {"Name":"Bud", "Age":"3"} 
] 

Я получаю ошибку:

"Could not create an instance of type Models.Dog. Type is an interface or abstract class and cannot be instantiated."

Указания Дискриминатора в формате JSON не помогает мне тоже. У кого-нибудь есть идеи? Благодаря!

Edit: Решение

Хитрость заключается в том, чтобы использовать свойство $ типа в строку JSON. Для получения дополнительной информации см. this link, предложенный m.t.bennett в комментариях.

Чтобы включить с помощью свойства $ типа мне нужно добавить следующее WebApiConfig.cs:

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling 
    = TypeNameHandling.Auto; 

Затем при проводке JSON к Скрипач, я добавил свойство $ типа с указанием полного пути объекта:

{"$type":"Example.Models.Dogs.GoldenRetriever, Example.Models", 
    "Name":"Bud","Age":3} 

Для того, чтобы понять это форматирование, я использовал предложение Snixtor для сериализации объекта и вывода строки JSON. Brilliant!

Я не уверен, что это самое элегантное решение, так как оно JSON.NET specific, но оно работает!

+2

я найти лучший способ для определения JSON форматирования для модели сериализовать существующий экземпляр * до * JSON. Вы пробовали это? – Snixtor

+0

@Snixtor Большой совет (и будет использовать его в будущем), но это не помогло. Я использовал JsonConvert для сериализации списка, и он выплюнул в основном то, что я уже пытался. Не было никаких признаков дискриминации между типами объектов. – brudert

+1

делает эту ссылку http://stackoverflow.com/questions/6348215/how-to-deserialize-json-into-ienumerablebasetype-with-newtonsoft-json-net вообще? –

ответ

0

Я использовал пользовательский JsonConverter для обработки десериализации базового типа.

public override bool CanConvert(Type objectType) { 
     return typeof(Mybase).Equals(objectType); 
    } 

    public override MyBase Deserialize(JsonReader reader, MyBase existingValue, JsonSerializer serializer) { 
     var ret = existingValue; 
     var jobj = JObject.ReadFrom(reader); 
     if (jobj["type"] == null || jobj["type"].Type != JTokenType.String) 
      throw new JsonSerializationException("Supplied JSON is missing the required 'type' member."); 

     var typeName = jobj["type"].Value<string>(); 

     var t = this.GetType().Assembly.GetType("MyNamespace." + typeName); 
     if(t == null) 
      throw new JsonSerializationException(String.Format("Could not identify supplied type '{0}' as a known type.", typeName)); 

     if (existingValue != null && !t.IsInstanceOfType(existingValue)) 
      throw new JsonSerializationException(String.Format("Type Mismatch: existingValue {0} is not assignable from supplied Type {1}", existingValue.GetType().Name, t.Name)); 

     ret = (ContactMethod)jobj.ToObject(t); 

     return ret; 
    } 

И зарегистрировал JsonConverter инициализации приложения durring:

JsonSerializerSettings settings; 
settings.Converters.Add(new MyBaseConverter()); 
Смежные вопросы