You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何在查询JSON JToken字段前判断其是否存在?

处理JSON可选字段的空值判断问题

你的程序崩溃的核心原因是:当total字段不存在时,result.SelectTokens("results.main[*].item.total")会返回空序列,此时调用First()会直接抛出InvalidOperationException——First()要求序列至少有一个元素,空序列会触发异常,你的空值判断根本没机会执行。

下面是几种可行的解决方法:

方法1:改用FirstOrDefault()替代First()

这是最直接的修改,FirstOrDefault()在序列为空时会返回null而非抛出异常,之后再做空值判断即可:

if (count > 0)
{
    var totalToken = result.SelectTokens("results.main[*].item.total").FirstOrDefault();
    var total = totalToken != null ? totalToken.ToString() : string.Empty;
}

方法2:先检查字段是否存在再取值

如果需要更精细的控制,可以遍历每个item节点,先判断total字段是否存在:

if (result.HasValues)
{
    foreach (var itemToken in result.SelectTokens("results.main[*].item"))
    {
        if (itemToken is JObject itemObj)
        {
            // 直接判断字段是否存在
            if (itemObj.ContainsKey("total"))
            {
                var total = itemObj["total"].ToString();
                // 处理total值
            }
            else
            {
                // 字段不存在时的逻辑
            }
        }
    }
}

方法3:使用强类型模型(推荐)

定义与JSON结构匹配的类,利用Json.NET的特性自动处理可选字段,这种方式类型更安全,代码可读性更高:

// 定义模型类
public class ResultRoot
{
    [JsonProperty("results")]
    public Results Results { get; set; }
}

public class Results
{
    [JsonProperty("copyright")]
    public string Copyright { get; set; }
    [JsonProperty("main")]
    public List<MainEntry> Main { get; set; }
}

public class MainEntry
{
    [JsonProperty("item")]
    public ItemData Item { get; set; }
}

public class ItemData
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("date")]
    public string Date { get; set; }
    // 可选字段用可空类型,不存在时自动为null
    [JsonProperty("total")]
    public long? Total { get; set; }
}

然后修改反序列化和取值逻辑:

// 改用异步await避免死锁(原代码的.Result可能导致死锁)
var response = await httpClient.GetAsync("getData.json?thing=abc");
response.EnsureSuccessStatusCode();
var jsonContent = await response.Content.ReadAsStringAsync();

var result = JsonConvert.DeserializeObject<ResultRoot>(jsonContent);

if (result?.Results?.Main != null && result.Results.Main.Count > 0)
{
    var firstItem = result.Results.Main[0].Item;
    var total = firstItem.Total.HasValue ? firstItem.Total.ToString() : string.Empty;
}

额外提示:原代码中使用.Result同步等待异步操作,容易在某些上下文(比如UI线程)导致死锁,建议改用await异步处理。

内容的提问来源于stack exchange,提问作者eek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:50:27