JsonDocument — дочерний объект для чтения

#c# #json

Вопрос:

У меня есть объект JSON, из которого я пытаюсь прочитать свойства. Вот пример:

 {"id":"335057af-a156-41c6-a0de-0cdc05856b3d",
"title":"Test 100488-100489 not included",
"code":"QWNCY47Y999",
"start":"2022-08-10T22:00:00.000Z",
"end":"2022-08-11T02:00:00.000Z",
"closeAfter":"2022-08-08T23:59:00.000Z",
"archiveAfter":"2022-11-08T22:00:00.000Z",
"timezone":"America/New_York",
"defaultLocale":"enUS",
"currency":"USD",
"registrationSecurityLevel":"Public",
"status":"Pending",
"eventStatus":"Upcoming",
"planningStatus":"In-Planning",
"testMode":true,
"planners":[{"firstName":"C","lastName":"G","email":"Noreply@events.qwerty.comx"}],
"created":"2021-06-11T09:55:57.667Z",
"lastModified":"2021-07-08T17:21:48.039Z",
"customFields":[
    {"id":"f2cf4864-171f-44fa-919a-248d37e42563",
    "name":"Level of Service",
    "value":["Full Support"],
    "type":"SingleSelect",
    "order":25},
    {"id":"c1539edf-a3e1-4f40-9747-e93f4fedfa5d",
    "name":"Internal/External",
    "value":["Internal","External"],
    "type":"MultiSelect",
    "order":42},
    {"id":"1b525d2a-b3f8-4141-91ae-45de5ee3a2fe",
    "name":"Request ID",
    "value":["MRF000558"],
    "type":"AutoIncrement",
    "order":53}],
"category":{"name":"Conference"},
"_links":{"invitation":{"href":"http://sandbox-www.qwerty.com/d/8nqg6n/1Q"},
"agenda":{"href":"http://sandbox-www.qwerty.com/d/8nqg6n/6X"},
"summary":{"href":"http://sandbox-www.qwerty.com/d/8nqg6n"},
"registration":{"href":"http://sandbox-www.qwerty.com/d/8nqg6n/4W"}},
"virtual":false,
"format":"In-person"}
 

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

 try 
{
        var x1 = content2.RootElement.GetProperty("code");      // it works
        var x2 = content2.RootElement.GetProperty("currency");   // it works
        var x3 = content2.RootElement.GetProperty("start");     // it works

        var x99 = content2.RootElement.GetProperty("summary");      // exception, key not found
        var x999 = x99.GetProperty("href");
}
catch(System.Exception ex)
{
        Console.WriteLine(ex.Message);
}
 

В конечном счете, моя цель-прочитать summary дочерний объект и получить свойство href .

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

1. Что-то еще должно быть не так, потому GetProperty() что работает с объектами JSON. Смотрите здесь: dotnetfiddle.net/zEqtm9

2. Я предполагаю, что KeyNotFoundException это не то, что вы думаете. Может быть, есть другое имя свойства, не показанное в примере, но которое вы неправильно указали?

Ответ №1:

у тебя ошибка. «краткое изложение» идет после «_links»

это работает для меня

 var contentObj = JObject.Parse(content);

var href = contentObj["_links"]["summary"]["href"]; 
 

выход

 http://sandbox-www.qwerty.com/d/8nqg6n
 

для тебя, я думаю, это могло бы быть

 var x9 = content2.RootElement.GetProperty("_links");
var x99 = x9.GetProperty("summary");     
 var x999 = x99.GetProperty("href").ToString();
//or just
var x999 = content2.RootElement.GetProperty("_links").GetProperty("summary").GetProperty("href").ToString();
 

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

1. Однако это Newtonsoft JSON. ОП использует System.Text.Json .

2. @GoodNightNerdPride Спасибо за уведомление. Я предлагаю, как это должно быть в text.json. Пожалуйста, проверьте мой обновленный ответ

3. Хороший улов с родительской собственностью _links . Это показывает, что красивые принтеры имеют свое применение ^^

4. @Serge — СПАСИБО. Я должен был бы разобраться в этом сам, но в свою защиту могу сказать, что я смотрел на это после полуночи. Из того, что я видел, это выглядело так, как будто GetProperty() не работало с дочерними объектами, но я ошибался.

Ответ №2:

Если это «но если одно из свойств является другим объектом, я не могу его прочитать». означает, что у вас нет четко определенного формата для файла JSON, просто создайте объект для файла JSON и десериализуйте его. Затем вы можете получить к нему доступ непосредственно через это свойство объектов.

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

1. Я надеюсь избежать определения объекта для десериализации. Этот объект исходит из стороннего API и может иметь несогласованный формат.

2. @Джо: Я согласен с тем, чтобы не десериализовывать все, если производительность вызывает больше беспокойства, чем удобочитаемость… но если json находится в несогласованном формате, у вашего метода та же проблема. Вы просто жестко кодируете формат в уродливых строках кода, а не в структуре класса.

3. @DevinBurke — Да, обычно я бы согласился. В этом случае добавление или удаление не связанного свойства в ответ не должно влиять на получение нужного мне свойства. Если то единственное свойство, которое мне нужно, больше не доступно через API, то все это придется переработать. Я думаю, что это просто меньшее из двух зол.