将未知的JSON字符串转换为正确的对象

时间:2018-06-23 11:18:01

标签: c# json unity3d

我从套接字连接中收到未知字符串。它始终遵循格式

{
    “eventType”: “playerListUpdate”
    “data”: “...changes...”
}

我正在使用以下方法反序列化它:

var message = JsonConvert.DeserializeObject<NetworkMessage>(data);

NetworkMessage 如下所示:

public class NetworkMessage
{
    public string data;
    public string eventType;
}

我的问题是,有时data属性保留为字符串,而有时它包含具有更复杂数据的数组(请考虑DB结果)。因此,当我尝试对数据数组中的字符串进行反序列化时,它将失败。

更复杂的数据的一个例子是

{"eventType":"latestPlayersList","data":[{"id":1,"firstName":"Harry"},{"id":2,"firstName":"Ted"},{"id":3,"firstName":"Michael"},{"id":4,"firstName":"Mike"}],"from":"server"}

如何根据 eventType 的值将JSON字符串反序列化为不同的VO?

2 个答案:

答案 0 :(得分:1)

反序列化的一种方法是直接转到JObject

var jObject = JsonConvert.DeserializeObject<JObject>(json);

现在您可以访问像这样的属性值:

var eventType = jObject.Value<string>("eventType")

现在,您还可以扩展它以检查eventType的值,然后反序列化为正确的对象类型。所以我们可以有一个像这样的通用类:

public class NetworkMessage<T>
{
    public string EventType;
    public T Data;
}

public class Player
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

然后根据eventType的值确定我们使用的泛型类型。请注意,这不是世界上效率最高的代码,因为它会反序列化两次,但它会起作用:

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

答案 1 :(得分:0)

您可以使用Newtonsoft.json。请尝试以下。

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

        }