解析API响应至Model时出现JSON解码错误:List非String类型
问题排查:JSON解码错误(List不是String类型)
问题描述
能正常获取API响应,但后续JSON解码时触发错误,提示内容为“List不是String类型”。
相关代码
Dio请求代码
import 'package:dio/dio.dart'; import 'package:dio_try/country_model.dart'; class DioClient { final Dio dio = Dio(); static const baseUrl = 'some Url'; Future<CountryListModel> fetchPost() async { try { dio.options.headers['Content-Type'] = 'application/json'; dio.options.headers['fcm_token'] = 'test'; final response = await dio.post(baseUrl); print(response.toString()); return CountryListModel.fromJson(response.data); } on DioError catch (e) { print(e.message + e.error); throw Exception(e.message + e.error); } } }
API返回的JSON响应
[ { "countryCode": "ALB", "countryName": "ALBANIA", "TypeId": "3", "eligible": "Y" } ]
Model类代码
import 'dart:convert'; List<CountryListModel> countryListModelFromJson(String str) => List<CountryListModel>.from( json.decode(str).map((x) => CountryListModel.fromJson(x))); String countryListModelToJson(List<CountryListModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class CountryListModel { CountryListModel({ required this.countryCode, required this.countryName, required this.TypeId, required this.eligible, }); String countryCode; String countryName; String TypeId; String eligible; factory CountryListModel.fromJson(Map<String, dynamic> json) => CountryListModel( countryCode: json["countryCode"], countryName: json["countryName"], TypeId: json["TypeId"], eligible: json["eligible"], ); Map<String, dynamic> toJson() => { "countryCode": countryCode, "countryName": countryName, "TypeId": TypeId, "eligible": eligible, }; static List<CountryListModel> countryListModelFromJson(List<dynamic> list) => List<CountryListModel>.from( list.map((x) => CountryListModel.fromJson(x))); }
错误原因
- API返回的是**数组(List)**结构,但Dio请求代码里直接调用
CountryListModel.fromJson(response.data)解析,而该方法仅支持解析单个对象的Map,与返回数据的List类型不匹配。 - Model类中已定义处理List的解析方法
countryListModelFromJson(List<dynamic> list),但请求代码未正确使用该方法。
修复方案
修改Dio请求方法的返回类型与解析逻辑
将fetchPost的返回类型改为Future<List<CountryListModel>>,并调用Model类中处理List的解析方法:
import 'package:dio/dio.dart'; import 'package:dio_try/country_model.dart'; class DioClient { final Dio dio = Dio(); static const baseUrl = 'some Url'; // 修改返回类型为List<CountryListModel> Future<List<CountryListModel>> fetchPost() async { try { dio.options.headers['Content-Type'] = 'application/json'; dio.options.headers['fcm_token'] = 'test'; final response = await dio.post(baseUrl); print(response.toString()); // 调用Model中处理List的解析方法 return CountryListModel.countryListModelFromJson(response.data); } on DioError catch (e) { print(e.message + e.error); throw Exception(e.message + e.error); } } }
优化Model类(可选,避免方法名冲突)
Model类存在两个同名的countryListModelFromJson方法,易引发混淆,建议重命名处理字符串的方法:
import 'dart:convert'; // 重命名处理字符串的方法 List<CountryListModel> countryListModelFromJsonString(String str) => List<CountryListModel>.from( json.decode(str).map((x) => CountryListModel.fromJson(x))); String countryListModelToJson(List<CountryListModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class CountryListModel { CountryListModel({ required this.countryCode, required this.countryName, required this.TypeId, required this.eligible, }); String countryCode; String countryName; String TypeId; String eligible; factory CountryListModel.fromJson(Map<String, dynamic> json) => CountryListModel( countryCode: json["countryCode"], countryName: json["countryName"], TypeId: json["TypeId"], eligible: json["eligible"], ); Map<String, dynamic> toJson() => { "countryCode": countryCode, "countryName": countryName, "TypeId": TypeId, "eligible": eligible, }; static List<CountryListModel> countryListModelFromJson(List<dynamic> list) => List<CountryListModel>.from( list.map((x) => CountryListModel.fromJson(x))); }
验证说明
修改完成后,API返回的List类型数据会被正确解析为List<CountryListModel>,类型不匹配的错误将不再出现。
内容的提问来源于stack exchange,提问作者Sam Verma
相关产品推荐
相关产品推荐

