优雅地解析JSON

时间:2018-11-01 10:17:17

标签: c# json.net asp.net-core-webapi

我在.NET Core 2.1中有一个Web api控制器,可以接收

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 :(得分:2)

根据official documentation-您可以执行以下操作:

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

See a live demo on rextester.

答案 1 :(得分:1)

这至少有点优雅:

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

答案 2 :(得分:0)

如果您不想反序列化完整的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}");