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

如何在C#中访问API返回的嵌套JSON数据?

如何在Unity中访问动态JSON结构的日期数据?

首先,先明确你拿到的JSON结构:API返回的data里是以年份字符串为键,每个年份下又以月份字符串为键,每个月份包含两个数组:consecutive(存储连续日期的数组组,比如[[11,12],[19,20,21]]表示11-12号连续、19-21号连续)和non_consecutive(存储单个的非连续日期,比如[4]表示4号是单独的)。

看你写的代码,能发现几个关键问题,咱们一步步修正:

问题1:混合使用dynamic和JsonData,遍历年份的方式错误

你的gamePlayLogsResponse是dynamic类型,但gamePlayLogsResponse["data"]是键值对集合(键是年份字符串,比如"2019"),不能用Count加索引循环遍历。另外你初始化了JsonData gameplayLogsData却没用到,可以统一用LitJSON的JsonData来处理,类型更明确。

问题2:consecutive数组的访问索引错误

你在遍历连续日期组的时候,用了gamePlayLogsResponse["data"][...]["consecutive"][i],但i是当前组内的日期索引,正确逻辑应该是先取第z个连续组,再取组内第i个日期:consecutive[z][i]。

问题3:non_consecutive的结构理解错误

non_consecutive是一维数组(比如[4]),不是二维数组,不需要嵌套循环,直接遍历每个元素就是日期值。

问题4:日期到UI元素的索引对应问题

你的_dateItems数组应该是按日期顺序排列的(索引0对应1号,索引1对应2号...),所以日期值减1才是对应的数组索引,比如日期11对应_dateItems[10]。


修正后的完整代码

// 统一用JsonData处理,避免dynamic的不确定性
JsonData gamePlayLogsResponse = JsonMapper.ToObject(userGameLogs.downloadHandler.text);
totalUnlockedLevels = 1;

if (gamePlayLogsResponse["status"].ToString() == "success")
{
    JsonData yearData = gamePlayLogsResponse["data"];
    // 遍历所有年份的键(比如"2019")
    foreach (string yearKey in yearData.Keys)
    {
        // 只处理当前选中的年份
        if (yearKey == CalendarController.year)
        {
            JsonData monthData = yearData[yearKey];
            // 只处理当前选中的月份,不用遍历12个月
            if (monthData.Has(CalendarController.month))
            {
                JsonData currentMonth = monthData[CalendarController.month];
                
                // 处理连续日期组
                JsonData consecutiveGroups = currentMonth["consecutive"];
                Debug.Log("连续日期组数量: " + consecutiveGroups.Count);
                foreach (JsonData dateGroup in consecutiveGroups)
                {
                    int groupLength = dateGroup.Count;
                    if (groupLength == 0) continue; // 跳过空数组
                    
                    for (int i = 0; i < groupLength; i++)
                    {
                        // 把日期转成int,再减1得到UI元素的索引
                        int date = (int)dateGroup[i];
                        int itemIndex = date - 1;
                        if (itemIndex < 0 || itemIndex >= calenderController._dateItems.Length)
                        {
                            Debug.LogWarning("日期" + date + "超出UI元素范围");
                            continue;
                        }
                        
                        Image dateImage = calenderController._dateItems[itemIndex].GetComponent<Image>();
                        if (i == 0)
                        {
                            dateImage.sprite = consStartSprite;
                        }
                        else if (i == groupLength - 1)
                        {
                            dateImage.sprite = consEndSprite;
                        }
                        else
                        {
                            dateImage.sprite = consContinueSprite;
                        }
                        Debug.Log("设置连续日期: " + date + " -> " + calenderController._dateItems[itemIndex].name);
                    }
                }
                
                // 处理非连续日期
                JsonData nonConsecutiveDates = currentMonth["non_consecutive"];
                Debug.Log("非连续日期数量: " + nonConsecutiveDates.Count);
                foreach (JsonData dateObj in nonConsecutiveDates)
                {
                    int date = (int)dateObj;
                    int itemIndex = date - 1;
                    if (itemIndex < 0 || itemIndex >= calenderController._dateItems.Length)
                    {
                        Debug.LogWarning("日期" + date + "超出UI元素范围");
                        continue;
                    }
                    
                    calenderController._dateItems[itemIndex].GetComponent<Image>().sprite = nonConsSprite;
                    Debug.Log("设置非连续日期: " + date + " -> " + calenderController._dateItems[itemIndex].name);
                }
            }
            else
            {
                Debug.LogWarning("当前月份" + CalendarController.month + "没有数据");
            }
        }
    }
}

关键优化点说明

  • 用JsonData替代dynamic,类型更安全,避免运行时意外错误
  • 直接遍历年份和月份的键,不用循环12个月,效率更高
  • 增加了索引越界判断,避免数组访问报错
  • 修正了连续日期组的索引访问逻辑,确保每个连续组的日期都能正确对应到UI元素
  • 简化了非连续日期的处理,因为它本身就是一维数组,不需要嵌套循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:04:46