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

Flutter解析本地JSON时报List<dynamic>不是Map<String,dynamic>子类型如何解决

问题修复方案

问题根源

你提供的JSON文件根结构是数组类型,json.decode(value)返回的是List<dynamic>,每个数组元素才是对应单本图书数据的Map<String, dynamic>,而你直接把整个List传给了只接收Map参数的BookData.fromJson,所以触发类型不匹配报错。
另外你自动生成的Id、PublishedDate类的解析逻辑也存在错误,和你提供的JSON结构不匹配,需要同步修正。

修复步骤

1. 修正getBooksAll方法逻辑

将方法改为异步返回Future<List<BookData>>,遍历解析后的JSON数组生成对应的BookData集合:

static Future<List<BookData>> getBooksAll() async {
  // 读取本地JSON字符串
  String booksJson = await rootBundle.loadString('assets/bookData.json');
  // 解析为List<dynamic>
  List<dynamic> jsonList = json.decode(booksJson);
  // 遍历每个元素转换为BookData
  return jsonList.map((jsonItem) => BookData.fromJson(jsonItem)).toList();
}

2. 修正Id类解析逻辑

你提供的示例JSON中_id是数字类型,如果实际业务中_id确实是这个结构,可以直接把BookData里的id字段类型改为int?,不需要嵌套Id类;如果是带$oid的嵌套结构,修正写法如下:

class Id {
  String? $oid;

  Id({this.$oid});

  Id.fromJson(Map<String, dynamic> json) {
    // 原写法错误,使用raw字符串直接取key为$oid的值
    this.$oid = json[r"$oid"];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data[r"$oid"] = this.$oid;
    return data;
  }
}

3. 修正PublishedDate类解析逻辑

class PublishedDate {
  String? $date;

  PublishedDate({this.$date});

  PublishedDate.fromJson(Map<String, dynamic> json) {
    // 原写法错误,使用raw字符串直接取key为$date的值
    this.$date = json[r"$date"];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data[r"$date"] = this.$date;
    return data;
  }
}

调用示例

上层调用getBooksAll时使用async/await即可拿到完整的图书列表:

// 示例调用逻辑
void loadBookList() async {
  List<BookData> allBooks = await BookData.getBooksAll();
  // 拿到列表后可直接用于UI渲染
}

内容的提问来源于stack exchange,提问作者a-starck02

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:48:02