[英]Trying to get first object out of an json array in C#
我正在尝试从 c# 中的 json 数组中获取第一个对象。 数组看起来像这样:
[
{
"name": "Joe",
"id": 1
},
{
"name": "Melinda"
"id": 2
}
]
我没有找到合适的方法来做到这一点,所以我在这里问。 我正在使用 System.Text.JSON。 我目前正在使用此代码:
class Program
{
public static void Main(String[] args)
{
HttpClient client = new HttpClient();
string url = "example.com";
string json = client.GetStringAsync(url).ToString()!;
Sensor sensor = JsonSerializer.Deserialize<Sensor>(json)!;
Console.WriteLine(sensor.id);
}
}
public class Sensor
{
public string? id { get; set; }
}
现在,不出所料,当我运行此代码时,System.Text.Json 会抛出一个错误,但我无法破译究竟是什么原因造成的(prbl bc 我很愚蠢):
inner exception System.Text.Json.JsonReaderException: 'S' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
at System.Text.Json.Utf8JsonReader.Read()
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
有没有一种简单的方法可以使用 System.Text.Json 或 Newtonsoft.Json 做到这一点? 谢谢
一种非常接近您的方法:
using System;
using System.Text.Json;
public class Program
{
public static readonly string data = @"[{""name"": ""Joe"",""id"": 1},{""name"": ""Melinda"", ""id"": 2 }]";
public static void Main()
{
// System.Text.Json defaults to case-sensitive property matching,
// so I need to switch this to insesitive, if the model adheres
// to C# naming convention ( Props start with capital letter)
JsonSerializerOptions jso = new JsonSerializerOptions(){ PropertyNameCaseInsensitive = true };
// We are deserializing an Array vv
var sensors = JsonSerializer.Deserialize<Sensor[]>(data, jso);
// I do an output for demonstration purposes.
// You'd want to check for null and size>0 and then use the first element.
foreach( var sensor in sensors )
{
Console.WriteLine($"{sensor.Id:#0} : {sensor.Name}");
}
}
}
public class Sensor
{
public int Id {get; set;}
public string Name {get; set;}
}
查看实际操作: https ://dotnetfiddle.net/t7Dkh8
另一个想法是增量解析,如果数组很长并且您只需要第一个元素,这是有益的。
请参阅C# 中的增量 JSON 解析(但需要 NewtonSoft)
我和 Jon Skeet 已经在评论中发表了另一句话:
您收到的错误消息
'S' 是一个无效的值开始。 行号:0 ...
提示接收到的字符串实际上可能不是有效的 json。 因此,您可能也想对此进行调查。
您可以设置一个断点并使用调试器查看该值,只需将其输出到文本文件中,或者如果您有日志记录,请将其记录下来。
您应该将 json 字符串反序列化为 new List(),然后您可以使用 FirstOrDefault() 方法找到列表的第一个元素,如下所示:
class Sensor
{
public int Id { get; set; }
public string Name { get; set; }
}
public Sensor GetFirstElementOfJsonArray(String data)
{
JsonSerializerOptions options = new JsonSerializerOptions(){
PropertyNameCaseInsensitive = true };
List<Sensor> sensorList=JsonConvert.Deserialize<List<Sensor>>(data,options);
return sensorList.FirstOrDefault();
}
我想,它会回答你的问题
我在您的问题中看到了两个问题。 首先是json中的id字段不是字符串而是整数。 所以你要么需要改变你的json,让它看起来像这样:
[
{
"name": "Joe",
"id": 1,
...
或更新您的 Sensor 类,使其如下所示:
public class Sensor
{
public int id { get; set; }
public string? name { get; set; }
}
一旦你这样做了,另一个问题是你的 json 不是一个对象,而是一个数组。 所以你的代码需要看起来更像这样:
HttpClient client = new HttpClient();
string url = "example.com";
string json = client.GetStringAsync(url).ToString()!;
var sensors = JsonSerializer.Deserialize<IEnumerable<Sensor>>(json)!;
Console.WriteLine(sensors.First().id);
因此,将 json 序列化为一个集合(IEnumerable),然后您可以查询该集合以获取您需要的任何数据。 另外,我不知道这是否只是代表性数据,但在您上面的 json 示例中,json 中的“Melinda”之后缺少逗号。
你需要反序列化到一个类:
public class Sensor {
public int Id { get; set; }
public string Name { get; set; }
}
JsonSerializer.Deserialize<Sensor>(json)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.