JsonConvert.Десериализует объект Object из API с использованием Webclient, который может быть одним из 2 типов объектов

#c# #json #object #serialization #dynamic

#c# #json #объект #сериализация #динамический

Вопрос:

Я пытаюсь получить доступ к API FitBit с помощью C #.Net Core 3.1

https://dev.fitbit.com/build/reference/web-api/sleep/

Однако для данных режима ожидания он может возвращать объект SleepJSON или метаобъект, который будет иметь длительность повторной попытки

 {
    "meta": {
        "retryDuration": 3000,
        "state": "pending"
    }
}
 

Если бы мне не приходилось иметь дело с этим мета-объектом, я бы просто сделал это, что работает до тех пор, пока я не получу другой.

var response = JsonConvert.DeserializeObject<SleepJSON>(await wc.DownloadStringTaskAsync($"{url}"));

Я довольно новичок в работе с API и пробовал использовать dynamic, однако я падаю, пытаясь определить, что было возвращено, а затем преобразовать их в тип объекта для использования.

Я действительно в недоумении, как справиться с этой ситуацией с 2 возможными типами возвращаемых объектов.

Комментарии:

1. Попробуйте десериализовать его одним типом. Если это не удается, попробуйте другой.

Ответ №1:

Когда вы не знаете, какой объект вы получаете (а действительно хорошие API либо избегают такого поведения, либо используют заголовки, чтобы дать вам подсказки о том, как читать содержимое), вместо того, чтобы полностью десериализовать содержимое, вы можете проанализировать ответ в JObject, проверить свойство верхнего уровня и выбратьсоответствующий путь, основанный на его существовании.

 var json = await wc.DownloadStringTaskAsync($"{url}");

var jObject = JObject.Parse(json);
if (jObject.Property("meta") != null)
{
    // handle meta here
    meta = jObject.ToObject<MetaResponse>();
}
else
{
    // you can fully deserialize the normal path here
    response = jObject.ToObject<SleepJSON>();
}
 

Комментарии:

1. Похоже, это ответ, который я добился успеха с небольшой модификацией if (JObject.Property(«meta») != null) {meta = JObject . ToObject<MetaResponse>(); } else { ответ = JObject . ToObject<SleepJSON>(); } Спасибо @David L

2. @bandworthy рад помочь и извиняется за свободный синтаксис. Я обновил свой ответ, чтобы он был немного более последовательным.