0

JSON:

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

Event handler:

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();
}

Error message: Cannot cast Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JToken

Stack trace:

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)
Liam Savage
  • 127
  • 6
  • 1
    `event_data` isn't a single value, what are you expecting to see in `eventData` variable? – Pavel Anikhouski Dec 12 '20 at 15:30
  • Hi @PavelAnikhouski, I am expecting the JSON string of event data, something along the lines of `{amount: 20},` – Liam Savage Dec 12 '20 at 15:30
  • It's a deserialization. Why would you expect a string? – Robert Harvey Dec 12 '20 at 15:31
  • See my question title, I am asking how to do this. – Liam Savage Dec 12 '20 at 15:33
  • Look at this example: https://www.newtonsoft.com/json/help/html/DeserializeObject.htm – Robert Harvey Dec 12 '20 at 15:35
  • That seems to be mapping to an object, which isn't what I want. – Liam Savage Dec 12 '20 at 15:38
  • Look at your JSON. It describes an object with two properties, `event_name` and `event_data`. The first is a string, the second is an object with on property, `amount`, a number. Create two classes with that structure and deserialize into an instance of the outer class. Or, deserialize into a `dynamic` and access the amount via `myDynamic.event_data.amount` – Flydog57 Dec 12 '20 at 15:39
  • @Flydog57 that isn't what I want, I need to get the string output of the `event_data` property's value, and send it elsewhere. A class doesn't help me here. – Liam Savage Dec 12 '20 at 15:41
  • OK, it looks like what you want is `JObject.Parse();`, not `JsonConvert.DeserializeObject()`. Have a look here: https://stackoverflow.com/a/44711550 – Robert Harvey Dec 12 '20 at 15:45
  • Or, you could deserialize things into `class MyClass { public string event_name {get; set;} public dynamic event_data {get; set; } }` and the re-serialize the `event_data` property. You may want to edit your question to make clear what you wsnt – Flydog57 Dec 12 '20 at 15:56

1 Answers1

0

You can do the following. Use JObject.Parse and use JObject instead of string. You can still get the inner json as a string using .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();

The value of eventData.ToString() will be:

event_data: {
    amount: 20
},
Peter Rasmussen
  • 16,474
  • 7
  • 46
  • 63