Reputation: 572
I’m receiving an unknown string from a socket connection. It always follows the format
{
“eventType”: “playerListUpdate”
“data”: “...changes...”
}
I’m deserialising it using:
var message = JsonConvert.DeserializeObject<NetworkMessage>(data);
With the NetworkMessage looking like this:
public class NetworkMessage
{
public string data;
public string eventType;
}
My problem is that sometimes the data property stays as a string, and other times it contains an array with more complex data (think DB results). So when I try to deserialise a string with an array in data, it fails.
An example of more complex data is
{"eventType":"latestPlayersList","data":[{"id":1,"firstName":"Harry"},{"id":2,"firstName":"Ted"},{"id":3,"firstName":"Michael"},{"id":4,"firstName":"Mike"}],"from":"server"}
How can I deserialise a JSON string into different VO depending on the value of eventType?
Upvotes: 2
Views: 1936
Reputation: 2143
You can use Newtonsoft.json. Try below.
var files = JObject.Parse(YourJSONHere);
var recList = files.SelectTokens("$..eventType").ToList();
for (int i = 0; i < recList.Count(); i++)
{
if (recList[i].ToString().Contains("latestPlayersList"))
{
var data = files.SelectTokens("$..data").ToList();
Console.Write(data.FirstOrDefault());
}
if (recList[i].ToString().Contains("playerListUpdate"))
{
var data = files.SelectTokens("$..data").ToList();
}
}
Upvotes: 0
Reputation: 119186
One way to deserialise is to go directly to a JObject
var jObject = JsonConvert.DeserializeObject<JObject>(json);
Now you can access property values like this:
var eventType = jObject.Value<string>("eventType")
Now you could also extend this to check the value of eventType
and then deserialise to the right object type. So we could have a generic class like this:
public class NetworkMessage<T>
{
public string EventType;
public T Data;
}
public class Player
{
public int Id { get; set; }
public string FirstName { get; set; }
}
And decide what the generic type we use based on the value of eventType
. Note, this isn't the most efficient code in the world as it deserialises twice, but it will work:
private void ProcessJson(string json)
{
var jObject = JsonConvert.DeserializeObject<JObject>(json);
switch (jObject.Value<string>("eventType"))
{
case "playerListUpdate":
HandlePlayerListUpdate(jObject.ToObject<NetworkMessage<string>>());
break;
case "latestPlayersList":
HandleLatestPlayersList(jObject.ToObject<NetworkMessage<List<Player>>>());
break;
}
}
private void HandlePlayerListUpdate(NetworkMessage<string> playerListUpdateMessage)
{
Console.WriteLine($"Player list update: {playerListUpdateMessage.Data}");
}
private void HandleLatestPlayersList(NetworkMessage<List<Player>> latestPlayersListMessage)
{
Console.WriteLine($"Latest Players list: {latestPlayersListMessage.Data.Count} players");
}
Upvotes: 2