Flutter集成ASP.NET Minimal API时jsonDecode类型不匹配问题解决
Flutter与ASP.NET Minimal API集成的JSON解析错误解决方法
你在Flutter调用ASP.NET Minimal API的MapGet接口时,遇到jsonDecode()报错:
Expected a value of type 'String', but got one of type 'List'
根本原因是API返回的不是标准JSON数组,而是包含半结构化字符串的列表,导致Flutter端无法正确解析。
你的Flutter代码
void main() async { final dio = Dio(); final response = await dio.get('https://localhost:7169/Result'); print(response.data); var json = jsonDecode(response.data); // Access the JSON values String name = json['Drainage_ID']; int age = json['date']; // Print the values print('id: $name'); print('tarikh: $age'); }
API实际返回格式
[ "'Drainage_ID': 'DR/C1/IC/H/-/GPG/PU/-/RCP/01','date':'10/5/2022 12:00:00 AM',", "'Drainage_ID': 'DR/C1/IC/H/-/GPG/PU/-/RCP/02','date':'10/5/2022 12:00:00 AM',", "'Drainage_ID': 'DR/C1/IC/H/-/GPG/SP/-/RCP/01','date':'10/5/2022 12:00:00 AM',", ... ]
你的ASP.NET Minimal API代码
app.MapGet("/Result", () => { var rows = new List<string>(); using var conn = new SqlConnection(connectionString); StringBuilder errorMessages = new StringBuilder(); conn.Open(); String query = "SELECT TOP 100 A.DR_PI_000_01 AS drainage_id,MAX(A.DR_PI_000_03) AS latest_time " + "\r\nFROM DR_PI_000 A\r\n\r\nGROUP BY A.DR_PI_000_01"; try { var command = new SqlCommand(query, conn); command.CommandTimeout = 1000; using SqlDataReader reader = command.ExecuteReader(); if (reader.HasRows) { while (reader!.Read()) { rows.Add($"'Drainage_ID': '{(reader.IsDBNull(0) ? null : reader?.GetString(0))}','date':'{(reader!.IsDBNull(1) ? null : reader?.GetDateTime(1))}',"); } } // … } catch (SqlException se) { for (int i = 0; i < se.Errors.Count; i++) { errorMessages.Append("Index #" + i + "\n" + "Message: " + se.Errors[i].Message + "\n" + "LineNumber: " + se.Errors[i].LineNumber + "\n" + "Source: " + se.Errors[i].Source + "\n" + "Procedure: " + se.Errors[i].Procedure + "\n"); } Console.WriteLine(errorMessages.ToString()); } return rows; }) .WithName("GetResult");
解决方法
方案一:修复ASP.NET API(推荐,标准做法)
问题出在API手动拼接字符串并返回字符串列表,ASP.NET会把它序列化为字符串数组,但每个元素不是合法JSON对象。正确做法是用实体类封装数据,让ASP.NET自动生成标准JSON。
- 创建数据实体类
public class DrainageResult { public string Drainage_ID { get; set; } public DateTime? Date { get; set; } }
- 修改API逻辑,返回实体列表
app.MapGet("/Result", () => { var rows = new List<DrainageResult>(); // 改为实体列表 using var conn = new SqlConnection(connectionString); StringBuilder errorMessages = new StringBuilder(); conn.Open(); String query = "SELECT TOP 100 A.DR_PI_000_01 AS drainage_id,MAX(A.DR_PI_000_03) AS latest_time " + "\r\nFROM DR_PI_000 A\r\n\r\nGROUP BY A.DR_PI_000_01"; try { var command = new SqlCommand(query, conn); command.CommandTimeout = 1000; using SqlDataReader reader = command.ExecuteReader(); if (reader.HasRows) { while (reader!.Read()) { var result = new DrainageResult { Drainage_ID = reader.IsDBNull(0) ? null : reader.GetString(0), Date = reader.IsDBNull(1) ? null : reader.GetDateTime(1) }; rows.Add(result); // 添加实体对象 } } // … } catch (SqlException se) { // 异常处理逻辑不变 for (int i = 0; i < se.Errors.Count; i++) { errorMessages.Append("Index #" + i + "\n" + "Message: " + se.Errors[i].Message + "\n" + "LineNumber: " + se.Errors[i].LineNumber + "\n" + "Source: " + se.Errors[i].Source + "\n" + "Procedure: " + se.Errors[i].Procedure + "\n"); } Console.WriteLine(errorMessages.ToString()); } return rows; }) .WithName("GetResult");
修改后API会返回标准JSON数组:
[ { "Drainage_ID": "DR/C1/IC/H/-/GPG/PU/-/RCP/01", "Date": "2022-10-05T00:00:00" }, { "Drainage_ID": "DR/C1/IC/H/-/GPG/PU/-/RCP/02", "Date": "2022-10-05T00:00:00" } ]
- 同步修改Flutter代码解析数组
void main() async { final dio = Dio(); final response = await dio.get('https://localhost:7169/Result'); print(response.data); // Dio会自动解析JSON,response.data已经是List<Map>,无需手动jsonDecode List<dynamic> jsonList = response.data; // 循环遍历每个元素 for (var json in jsonList) { String id = json['Drainage_ID']; DateTime date = DateTime.parse(json['Date']); print('id: $id'); print('tarikh: $date'); } }
方案二:Flutter端兼容(不推荐,仅应急)
如果暂时无法修改API,可在Flutter端手动处理非标准格式:
void main() async { final dio = Dio(); final response = await dio.get('https://localhost:7169/Result'); List<String> stringList = response.data; for (var itemStr in stringList) { // 清理字符串并包裹成合法JSON对象 String cleanedStr = "{$itemStr}".replaceAll(',}', '}'); var json = jsonDecode(cleanedStr); String id = json['Drainage_ID']; DateTime date = DateTime.parse(json['date']); print('id: $id'); print('tarikh: $date'); } }
内容的提问来源于stack exchange,提问作者user21497668
相关产品推荐
相关产品推荐

