Flutter集成ASP.NET API时Bloc搜索及数据显示异常求助
问题定位
类型转换异常根源
- Dio默认会自动将JSON响应解析为
Map<String, dynamic>,你额外调用jsonDecode(response.data)属于重复解析,易引发类型混乱。 - 错误将API返回的
result字段(实际是单个listmodel结构)当成可迭代数组,用map生成List<listmodel>,导致每个listmodel初始化时传入的是rows子项(_JsonMap类型),而非完整的listmodel结构,触发类型不匹配异常。
- Dio默认会自动将JSON响应解析为
ListView显示异常根源
snapshot.data被声明为List<listmodel>,但实际每个listmodel内部的rows才是业务数据列表。你在ListView.builder中用外层index访问rows![index],既可能引发索引越界,又错误绑定了外层列表索引与rows项,最终显示对象引用而非字段值。
解决方案
1. 修复fetchUsers方法
调整API响应解析逻辑,直接用完整响应结构初始化listmodel,并传递rows列表到数据流:
Future<void> fetchUsers() async { final Dio _dio = Dio(); const String _url = 'https://juslinkhere.com/c&s/here/all'; try { // Dio自动解析JSON,无需额外jsonDecode Response response = await _dio.get( _url, options: Options(headers: {"key": "token"}), // 修复headers格式错误 ); // 用整个响应数据初始化listmodel final listmodel model = listmodel.fromJson(response.data); // 传递rows列表到数据流,而非listmodel列表 userBloc.userController.sink.add(model.rows ?? []); } catch (error, stacktrace) { print("Exception occured: $error stackTrace: $stacktrace"); // 可选:错误时传递空列表避免UI崩溃 userBloc.userController.sink.add([]); } }
2. 调整StreamBuilder与ListView代码
将数据流类型改为List<Rows>,直接遍历rows列表渲染字段:
Widget UsersWidget(){ return StreamBuilder<List<Rows>>( stream: userBloc.userController.stream, builder: (BuildContext context, AsyncSnapshot<List<Rows>> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text("无数据")); } return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (BuildContext context, int index){ final row = snapshot.data![index]; return Card( child: ListTile( title: Text(row.id ?? "无ID"), subtitle: Text(row.dateoflastinsp ?? "无检查日期"), leading: const Icon(Icons.edit_road), trailing: const Icon(Icons.arrow_forward), onTap:() { Navigator.push( context, MaterialPageRoute(builder: (context)=> DetailsScreen(index)) ); }, ), ); } ); } ); }
3. 更新BLoC数据流类型
确保userBloc中的userController对应正确的数据流类型:
class UserBloc { final StreamController<List<Rows>> _userController = StreamController<List<Rows>>(); Stream<List<Rows>> get userStream => _userController.stream; StreamSink<List<Rows>> get userController => _userController.sink; void dispose() { _userController.close(); } }
额外优化建议
- 为Model类添加空安全兜底处理,避免空指针异常(如用
??提供默认值)。 - 为API请求添加超时、无网络等异常捕获逻辑,提升容错性。
- 推荐使用
json_serializable库自动生成Model序列化代码,减少手动编写错误。
内容的提问来源于stack exchange,提问作者user21497668
相关产品推荐
相关产品推荐

