Я использую System.Net.Http.HttpClient, версию, доступную в настоящее время в NuGet, для извлечения данных из сервис в формате json. Данные примерно выглядят так:
{
"schema": "Listing",
"data": {
"key": "28ba648c-de24-45d4-a7d9-70f810cf5438",
"children": [{
"kind": "type1",
"data": {
"body": "Four score and seven years ago...",
"parent_id": "2qh3l",
"report_count": 0,
"name": "c4j6yeh"
}
}, {
"kind": "type3",
"data": {
"domain": "abc.def.com",
"flagged": true,
"category": "news",
"saved": false,
"id": "t3dz0",
"created": 1335998011.0
}
}]
}
}
Я использую HttpContentExtensions.ReadAsAsync<T>
для десериализации эту строку json в граф объектов. Определения типов выглядят примерно так:
public class Response
{
public String schema { get;set; }
public ListingData data { get;set; }
}
public class ListingData
{
public string key { get;set; }
public List<OneItem> children { get;set; }
}
Вот проблема: я хочу, чтобы тип элементов в children
менялся в зависимости от свойства kind
. Если kind
является "type1", то я хочу десериализовать объект... назовем его Type1
. Если kind
имеет тип 3, то мне нужен объект типа Type3
.
Прямо сейчас я могу десериализовать List<Type1>
или List<Type3>
, но я не знаю, как заставить логику десериализации различать их.
Я мог бы объединить все свойства объекта данных "type1" и объекта данных "type3" в один тип .NET. Но количество свойств достаточно велико, и это становится беспорядочным.
Если бы имя свойства в JSON (в данном случае data
) было другим, я мог бы отличить его. Если бы, например, данные выглядели так:
"children": [{
"kind": "type1",
"t1data": { ... }
}, {
"kind": "type3",
"t3data": { ... }
}]
... тогда я мог бы сделать что-то подобное в .NET:
public class OneItem
{
public string kind { get;set; }
public Type1 t1data { get;set; }
public Type3 t3data { get;set; }
}
Но моя схема данных не выглядит так.
Можно ли выбрать тип десериализации по содержанию данных? Другими словами, просмотрите значение одного свойства (в данном случае kind
), чтобы определить, как десериализовать содержимое для другого свойства (в данном случае data
).
Или можно внедрить фильтр или преобразователь, который воздействует на JSON до того, как ReadAsAsync попытается его десериализовать?
Если да, то как?