Преобразование неизвестной строки JSON в правильный объект - PullRequest
0 голосов
/ 23 июня 2018

Я получаю неизвестную строку из сокетного соединения.Он всегда следует формату

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

Я десериализовываю его, используя:

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

Когда NetworkMessage выглядит следующим образом:

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

Моя проблема в том, что иногда свойство данных остается в виде строки, а иногда оно содержит массив с более сложными данными (например, результаты БД).Поэтому, когда я пытаюсь десериализовать строку с массивом в данных, происходит сбой.

Примером более сложных данных является

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

Как я могу десериализовать строку JSON в разные VO в зависимости отна значение eventType ?

Ответы [ 2 ]

0 голосов
/ 23 июня 2018

Вы можете использовать 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();
            }

        }
0 голосов
/ 23 июня 2018

Один из способов десериализации - перейти непосредственно к 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");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...