C# 按属性名从JSON获取值时如何处理System.ArgumentOutOfRangeException错误

C# 按属性名从JSON获取值时如何处理System.ArgumentOutOfRangeException错误,c#,json,linq,C#,Json,Linq,我可以使用以下代码成功地从以下JSON中提取数据: string json = @"{ "person": { "name": "John", "age": 30, "cars": [ { "make": "Ford", "model": "Focus", "year": 2003 }, { "make": "Toyota", "model": "Yar

我可以使用以下代码成功地从以下JSON中提取数据:

string json = @"{
  "person": {
    "name": "John",
    "age": 30,
    "cars": [
      {
        "make": "Ford",
        "model": "Focus",
        "year": 2003
      },
      {
        "make": "Toyota",
        "model": "Yaris",
        "year": 2015
      }
    ]
  }
}";

JObject rss = JObject.Parse(json);

string name = (string)rss["person"]["name"];
//This will return John

string car1 = (string)rss["person"]["cars"][0]["make"];
//This will return Ford

string car2 = (string)rss["person"]["cars"][1]["make"];
//This will return Toyota
如果JSON发生变化,并且car数组只包含一项,那么我会得到以下car2错误:

“System.ArgumentOutOfRangeException”类型的未处理异常 在mscorlib.dll中发生其他信息:索引已超出 范围必须为非负数且小于集合的大小

这是因为car数组的位置1中没有项目。如果发生这种情况,我希望将car2字符串设置为空字符串

在尝试提取值之前,是否有办法检查项目是否存在

我在下面加入了psuedocode来解释我想要实现的目标:

if exists(rss["person"]["cars"][1]["make"])
then string car2 = (string)rss["person"]["cars"][1]["make"]
else string car2 = ""
提前谢谢


参考资料-

我想你可能需要先检查一下汽车的数量

JArray cars = (JArray)rss["person"]["cars"];
string car1 = "";
string car2 = "";
if(cars.Count > 0)
{
   car1 = (string)cars[0]["make"];
}

if(cars.Count > 1)
{
   car2 = (string)cars[1]["make"];
}

检查一下我想你可能需要先检查一下汽车的数量

JArray cars = (JArray)rss["person"]["cars"];
string car1 = "";
string car2 = "";
if(cars.Count > 0)
{
   car1 = (string)cars[0]["make"];
}

if(cars.Count > 1)
{
   car2 = (string)cars[1]["make"];
}

选中

您可以使用
JsonConvert.DeserializedObject
方法将json字符串转换为类型化对象。根据提供的输入,Json类将表示如下:

public class Car
{
    public string make { get; set; }
    public string model { get; set; }
    public int year { get; set; }
}

public class Person
{
    public string name { get; set; }
    public int age { get; set; }
    public List<Car> cars { get; set; }
}

public class PersonResponse
{
    public Person person { get; set; }
}
var personResponse = JsonConvert.DeserializeObject<PersonResponse>(json);
和car2作为

if (personResponse.Person.cars != null && personResponse.Person.cars > 1)
{
    car2 = personResponse.Person.cars[1].make;
}
使用上述类型化类,您不需要自己键入casting


DeserializeObject
定义引用于。

您可以使用
JsonConvert.DeserializedObject
方法将json字符串转换为类型化对象。根据提供的输入,Json类将表示如下:

public class Car
{
    public string make { get; set; }
    public string model { get; set; }
    public int year { get; set; }
}

public class Person
{
    public string name { get; set; }
    public int age { get; set; }
    public List<Car> cars { get; set; }
}

public class PersonResponse
{
    public Person person { get; set; }
}
var personResponse = JsonConvert.DeserializeObject<PersonResponse>(json);
和car2作为

if (personResponse.Person.cars != null && personResponse.Person.cars > 1)
{
    car2 = personResponse.Person.cars[1].make;
}
使用上述类型化类,您不需要自己键入casting


反序列化对象
定义在中引用。

JsonPath
在这里非常有用。首先将cars数组存储在一个单独的变量中,然后可以从中获取最后一个或第一个元素。为什么不将json反序列化为类结构呢。在这种情况下,汽车将转换为
IEnumerable
对象,您可以在其中检查
计数
?此外,反序列化到一个类型将提供额外的功能,因此您不需要自己进行类型转换。当
cars
只有1项时,它将仅是
{}
中的1项,还是将位于数组
[{}]
中?我认为这是问题的根源。我完全同意User1672994,反序列化到一个真实的对象,并从那里使用LinQ。当您只想将对象的一部分解析为真实对象,但仍然不想解析整个对象时,LinQ2Json更有用。
JsonPath
在这里非常有用。首先将cars数组存储在一个单独的变量中,然后可以从中获取最后一个或第一个元素。为什么不将json反序列化为类结构呢。在这种情况下,汽车将转换为
IEnumerable
对象,您可以在其中检查
计数
?此外,反序列化到一个类型将提供额外的功能,因此您不需要自己进行类型转换。当
cars
只有1项时,它将仅是
{}
中的1项,还是将位于数组
[{}]
中?我认为这是问题的根源。我完全同意User1672994,反序列化到一个真实的对象,并从那里使用LinQ。当您只想将对象的一部分解析为真实对象,但仍然不想解析整个对象时,LinQ2Json更有用。