Парс JSON элегантно - PullRequest
       10

Парс JSON элегантно

0 голосов
/ 01 ноября 2018

У меня есть контроллер веб-API в .NET Core 2.1, который получает

JToken jsonBody

JSON имеет следующую структуру

{
  "id": "xxx",
  "payload": {
    "TelephoneNumber": "1111",
    "Name": "Hans"
  }
}

и более полей, но это не имеет значения. Я хочу получить номер и имя элегантно. В настоящее время я делаю следующее, что, я уверен, могло бы быть сделано лучше:

var payload = JObject.Parse(jsonBody.SelectToken("Payload").ToString());
            telephoneNumber = new TelephoneNumber(payload.SelectToken("TelephoneNumber").ToString());

Я пытался просто сделать

jsonBody.SelectToken("Payload.TelephoneNumber")

но это не работает. Я думаю, это потому, что каким-то образом jsonBody, который получает контроллер, проанализировал только верхние узлы как json, поэтому может случиться так, что он учитывает значение

jsonBody.SelectToken("Payload")

в виде строки.

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Согласно официальной документации - вы можете сделать что-то вроде этого:

var phone = jsonBody["payload"]["TelephoneNumber"].ToString();
var name = jsonBody["payload"]["Name"].ToString();

Смотрите живую демонстрацию на rextester.

0 голосов
/ 01 ноября 2018

Если вы не хотите десериализовать свой полный JSON, вы можете создать класс с нужными вам свойствами

public class Payload
{
    public string TelephoneNumber { get; set; }
    public string Name { get; set; }
}

А затем используйте JsonTextReader для десериализации строки:

private static Payload DeserializePayload(JToken token)
{
    var serializer = new JsonSerializer();

    using (JsonTextReader reader = new JsonTextReader(new StringReader(token.ToString())))
    {
        reader.CloseInput = true;

        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.StartObject && reader.Path.Equals("payload"))
            {
                var payload = serializer.Deserialize<Payload>(reader);
                return payload;
            }
        }
    }

    // not found - return null? throw exception?
    return null;
}

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

var token = JToken.Parse(@"{
  ""id"": ""xxx"",
  ""payload"": {
    ""TelephoneNumber"": ""1111"",
    ""Name"": ""Hans""
  }
}");

Payload payload = DeserializePayload(token);

Console.WriteLine($"Name: {payload.Name}, Phone number: {payload.TelephoneNumber}");
0 голосов
/ 01 ноября 2018

Это, по крайней мере, немного элегантнее:

var jsonBody = JObject.Parse(@"{
  'id': 'xxx',
  'payload': {
    'TelephoneNumber': '1111',
    'Name': 'Hans'
  }
}");

var phone = jsonBody["payload"]["TelephoneNumber"].Value<string>();
var name = jsonBody["payload"]["Name"].Value<string>();
...