Как получить строковое значение ключа из вложенного объекта JSON?

#c#

#c#

Вопрос:

JSON:

 {
    event_name: 'request_queue_items',
    event_data: {
        amount: 20
    },
}
 

Обработчик событий:

 private void OnMessage(string message)
{
    if (!message.Contains("{") || !message.Contains("}"))
    {
        return; // It's not JSON, we don't care...
    }
    
    var jsonObject = (JObject)JsonConvert.DeserializeObject(message);

    var eventName = jsonObject["event_name"].Value<string>();
    var eventData = jsonObject["event_data"].Value<string>();
    
    Console.WriteLine("RECEIVED: "   eventName);
    Console.WriteLine("WITH DATA: "   eventData);
    Console.WriteLine();
    Console.WriteLine();
}
 

Сообщение об ошибке: Cannot cast Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JToken

Трассировка стека:

 12/12/2020 15:19:07 [Error] Application Error System.InvalidCastException: Cannot cast Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JToken.
   at Newtonsoft.Json.Linq.Extensions.Convert[T,U](T token)
   at Newtonsoft.Json.Linq.Extensions.Value[T,U](IEnumerable`1 value)
   at Newtonsoft.Json.Linq.Extensions.Value[U](IEnumerable`1 value)
 

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

1. event_data это не единственное значение, что вы ожидаете увидеть в eventData переменной?

2. Привет @PavelAnikhouski, я ожидаю строку данных события в формате JSON, что-то вроде {amount: 20},

3. Это десериализация. Почему вы ожидаете строку?

4. Смотрите Заголовок моего вопроса, я спрашиваю, как это сделать.

5. Посмотрите на этот пример: newtonsoft.com/json/help/html/DeserializeObject.htm

Ответ №1:

Вы можете сделать следующее. Используйте JObject.Parse и используйте JObject вместо string . Вы все равно можете получить внутренний json в виде строки, используя .toString():

 if (!message.Contains("{") || !message.Contains("}"))
{
    return; // It's not JSON, we don't care...
}

var jsonObject = JObject.Parse(message); // use JObject

var eventName = jsonObject["event_name"].Value<string>();
var eventData = jsonObject["event_data"].Value<JObject>(); //use JObject as it is not a string

Console.WriteLine("RECEIVED: "   eventName);
Console.WriteLine("WITH DATA: "   eventData);
Console.WriteLine();
 

Значение EventData.toString() будет:

 event_data: {
    amount: 20
},