【问题标题】:Read a JSON property with NULL handling using JSON.Net使用 JSON.Net 读取具有 NULL 处理的 JSON 属性
【发布时间】:2018-01-15 07:06:23
【问题描述】:

我有一个如下所示的 JSON 结构来显示特定候选人的详细信息 它可以是 null 也可以包含一些详细信息,如下所示

     "details": {
        "gender": {
          "id": 3,
          "props": {
            "name": "male"
          }
        }
    }

    or as null

    "details": {
        "gender": null
    }

为了读取我尝试过的性别值

 string _gender = (string)result["details"]["gender"]["props"]["name"];  

这将适用于非空情况。但如果它为 null,则此代码返回异常

所以首先检查它是否为空,如果不为空,请尝试读取该值,我尝试了下面的代码

        string _gender = (string)result["details"]["gender"];
        if (!string.IsNullOrEmpty(_gender))
        {
            _gender = (string)result["details"]["gender"]["props"]["name"]; 
        }

但我得到了无法将对象转换为字符串的异常。那么如何通过正确的 null 处理读取 JSON 属性 \

【问题讨论】:

  • 为什么不将其反序列化为性别可以为空的类型?
  • gender 只是 JArray 的一个属性。
  • 你仍然可以反序列化它。如果您将Json2C# 与完整的json 一起使用,则可以将details 的类型设置为可为空并将您的json 反序列化为一个对象,例如List<YourObject>。然后获取所有实例的 details 属性。
  • 也许只是if(result["details"]["gender"] != null) ?请记住,result["details"]["gender"] 的类型是 JToken,而不是字符串
  • 看起来像 Json.NET get nested jToken value 的副本。同意吗?

标签: c# json json.net


【解决方案1】:

我强烈建议您将 json 反序列化为已知类型。

public class Props
{
    public string name { get; set; }
}

public class Gender
{
    public int id { get; set; }
    public Props props { get; set; }
}

public class Details
{
    public Gender gender { get; set; }
}

public class JsonObject
{
    public Details details { get; set; }
}

然后进行反序列化;

var jsonObject = JsonConvert.DeserializeObject<List<JsonObject>>(json);
foreach (var o in jsonObject)
{
    var genderName = o?.details?.gender?.props?.name;
}

这样就可以处理可能的空值,得到强类型对象。

编辑

另外,在您的代码中,您试图将对象转换为字符串,这是完全错误的。看来gender 对象是一个复杂类型。所以你不能把它转换成字符串,你应该像这样修改你的代码;

object _gender = result["details"]["gender"];
if (_gender != null)
{
    string genderName = result["details"]["gender"]["props"]["name"].ToString();
}

【讨论】:

  • 对不起,json本质上是高度动态的,所以很难在整个json上设置所有可以为空和不可为空的属性进行解析。这种性别只是我正在努力解析的属性之一。我正在尝试找到一种解决方案来解决可空的 JToken 解析基本上
【解决方案2】:

请记住,jToken[xx..][yy..] 不是一个字符串,它是一个 JToken 对象,因此我们不能将它显式地转换为字符串。如果我们想将它转换为字符串,我们必须显式地调用ToString()(在术语上调用JToken 的.ToString 的覆盖实现)。

首先,我们需要检查 Jtoken 是否具有我们拥有方法 .HasValues 的值。 稍后当我们确定 ["name"] 中有一个字符串时 我们可以使用的属性 - 显式转换或 .ToString() 再次

string _gender;
var genderToken = jToken["details"]["gender"];
if (genderToken.HasValues)
{
    _gender = genderToken["props"]["name"].ToString();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 2017-01-14
    相关资源
    最近更新 更多