C# Newtonsoft.Json кастомная десириализация
У меня есть JSON следующей структуры:
{
data: [
{
{
"id": 1615765077617,
"type": "feed",
"attributes": {
"from": { ... },
"message": "Ignat добавил проект <a href=\"https://freelancehunt.com/project/opublikovat-prilozhenie-appstore-sozdano/855530.html\">Опубликовать приложение в AppStore - Создано в Unity</a>",
"is_new": false,
"created_at": "2021-03-15T01:37:58+02:00"
},
"links": { ... }
}
... // такие же по структуре элементы
],
... // остальной контент
}
И такой класс:
public class FhFeed
{
public string Message { get; set; }
public bool IsNew { get; set; }
public DateTime CreatedAt { get; set; }
}
Как видно, мне нужны только данные из attributes. Я хочу, что бы я мог просто написать:
var feed = JsonConvert.DeserializeObject<FhFeed[]>(jsonString);
Я видел, что этого можно добится сделав свой конвертер (вот тут про это). Но я не увидел там каких-либо нетривиальных примеров, и не могу разобратся, как пропустить ненужную инфу до определённого токена, например.
Ответы (1 шт):
Я любитель потоковой обработки данных: если можно что-то обработать по частям, не загружая целиком в память, не потребляя лишних ресурсов, то так и следует делать.
К моему личному сожалению, потоковая обработка таких форматов, как xml/json и прочих мало распространена. Поэтому хочу показать пример.
var feeds = new List<FhFeed>();
var serializer = new JsonSerializer();
using (var textReader = new StreamReader("test.json"))
using (var jsonReader = new JsonTextReader(textReader))
{
while (jsonReader.Read())
{
if (jsonReader.TokenType == JsonToken.PropertyName &&
(string)jsonReader.Value == "attributes")
{
_ = jsonReader.Read();
var feed = serializer.Deserialize<FhFeed>(jsonReader);
feeds.Add(feed);
}
}
}
Конечно, тут есть нюанс: мы опираемся на свойство "attributes". Если в json есть свойства с таким же именем в других местах, то этот код окажется нерабочим. Тогда придётся вводить дополнительные проверки.
Тут могут сказать, что поэтому и боятся использовать JsonReader. Но если писать конвертер, то там придётся делать те же самые проверки.