1

Есть JSON:

{
  "Table1": {
    "Field1": "abc",
    "Field2": "def"
  }
}

И есть код:

JObject data = JObject.Parse(myJson);
foreach (JProperty table in data.Properties())
{
    tables.Add(table.Name, new TableFields(table.Value<JObject>())); // <- тут ошибка
}

При выполнении кода выдает исключение InvalidCastException и говорит, что невозможно преобразовать значение в JObject. Почему так?


Пока что я прописал костыль JObject.Parse(table.Value.ToString()). Но далее я пытаюсь у полей со строками получить значения в формате String и опять получаю эту ошибку. Вот код:

public TableFields(JObject source)
{
    data = new Dictionary<string, string>();
    foreach (JProperty prop in source.Properties()) data.Add(prop.Name, prop.Value<String>());
}

Что это за бред такой? Тем более у этих JProperty в поле Type везде указаны именно те типы, к которым я пытаюсь привести: JObject в первом случае и String во втором.

Espeon
  • 537
  • Вы бы привели соурс чего там парсите в читаемом виде, так догадаться невозможно. А tables класс что из себя представляет? – NewView Jan 16 '19 at 03:26
  • В самом начале приведен JSON. – Espeon Jan 16 '19 at 03:38
  • замени на (JObject)table.Value – Grundy Jan 16 '19 at 03:59
  • @Grundy А во втором случае что делать? – Espeon Jan 16 '19 at 04:09
  • ничего, он работает – Grundy Jan 16 '19 at 06:04
  • Ваш json имеет простую классическую структуру, поэтому десериализацию можно провести штатными средствами JsonConvert.Deserialize<MyType>(data). Вместо этого вы пошли читать и разбирать структуру на более низком уровне, что делается крайне редко и только для кастомных json-объектов. Скажите, у вас чем-то мотивирована такая потребность или вас устроит типовое решение по десериализации json.net? – A K Jan 16 '19 at 06:08
  • @AK, набор полей-то меняется – Grundy Jan 16 '19 at 06:10
  • @Grundy Во-первых, из приведённого json этого не видно. Во-вторых, есть классическая закрывашка на ассоциированные массивы. Вон, даже сам автор создал Dictionary<string, string>() – A K Jan 16 '19 at 06:13
  • @AK Я не думал о таком подходе. Возможно, что такое решение мне подойдет. Сейчас пойду пробовать. – Espeon Jan 16 '19 at 06:19
  • @AK, любой json можно как dictionary, Но потом с ним не всегда удобно работать – Grundy Jan 16 '19 at 06:22
  • Удобно только если весь JSON состоит только из строк. Но сейчас это как раз такая ситуация. @AK вы можете оформить это в виде ответа. Я его отмечу. – Espeon Jan 16 '19 at 06:29
  • @Eevee Можно гораздо проще - закрыть как дубликат вопроса. – A K Jan 16 '19 at 06:41

1 Answers1

0

Используемый вами метод Extensions.Value<T>(this IEnumerable<JToken> value) пытается преобразовать в указанный вами тип не значение свойства JProperty, а само свойство (пару из ключа и значения). Такая операция не имеет смысла, отсюда и ошибка.

Вместо этого следует использовать свойство JProperty.Value, чтобы получить именно значение свойства:

(JObject)table.Value
(string)prop.Value

Также можно использовать сначала свойство Value, а потом - метод:

table.Value.Value<JObject>()
prop.Value.Value<string>()
Pavel Mayorov
  • 58,537
  • Точно. Это именно то, что я хотел узнать. Я попробовал и так все действительно заработало. – Espeon Jan 16 '19 at 06:54