繁体   English   中英

试图从 C# 中的 json 数组中获取第一个对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM