如何将含自定义Event类的DateTime-List<Event> Map转为JSON?
解决Dart中Map<DateTime, List>的JSON序列化/反序列化问题
报错原因
json.encode只能处理Dart原生可序列化类型(比如字符串、数字、原生List/Map等),你的代码里两个关键点不符合要求:
- Map的键是
DateTime类型,JSON不支持非字符串作为键 Event是自定义类,默认没有实现序列化逻辑
解决方案步骤
1. 给Event类添加序列化/反序列化方法
修改Event类,增加toJson方法把对象转成可序列化的Map,再增加工厂方法fromJson把Map转回Event:
class Event { final String title; Event({required this.title}); // 转成可序列化的Map Map<String, dynamic> toJson() { return {'title': title}; } // 从Map转成Event对象 factory Event.fromJson(Map<String, dynamic> json) { return Event(title: json['title'] as String); } @override String toString() => title; }
2. 实现Map转JSON的逻辑
需要把原Map的DateTime键转成ISO格式字符串,同时把List<Event>转成List<Map>:
// 把Map<DateTime, List<Event>>转成可序列化的Map<String, List<Map>> Map<String, dynamic> convertSelectedEventsToJson(Map<DateTime, List<Event>> events) { return events.map((key, value) => MapEntry( key.toIso8601String(), // DateTime转ISO字符串作为键 value.map((event) => event.toJson()).toList(), // 每个Event转成Map )); } // 使用示例 final jsonString = json.encode(convertSelectedEventsToJson(selectedEvents!)); print(jsonString);
3. 实现JSON转回Map的逻辑
把JSON里的字符串键转回DateTime,同时把List<Map>转回List<Event>:
// 把JSON字符串转回Map<DateTime, List<Event>> Map<DateTime, List<Event>> convertJsonToSelectedEvents(String jsonString) { final jsonMap = json.decode(jsonString) as Map<String, dynamic>; return jsonMap.map((key, value) => MapEntry( DateTime.parse(key), // 字符串转DateTime (value as List).map((item) => Event.fromJson(item as Map<String, dynamic>)).toList(), // Map转Event )); } // 使用示例 final restoredEvents = convertJsonToSelectedEvents(jsonString);
完整测试代码
import 'dart:convert'; class Event { final String title; Event({required this.title}); Map<String, dynamic> toJson() { return {'title': title}; } factory Event.fromJson(Map<String, dynamic> json) { return Event(title: json['title'] as String); } @override String toString() => title; } void main() { // 模拟有数据的selectedEvents final selectedEvents = <DateTime, List<Event>>{ DateTime.now(): [Event(title: '会议'), Event(title: '健身')], }; // 转JSON final jsonMap = selectedEvents.map((key, value) => MapEntry( key.toIso8601String(), value.map((e) => e.toJson()).toList(), )); final jsonString = json.encode(jsonMap); print('序列化后的JSON: $jsonString'); // 反序列化回原Map final decodedMap = json.decode(jsonString) as Map<String, dynamic>; final restoredEvents = decodedMap.map((key, value) => MapEntry( DateTime.parse(key), (value as List).map((item) => Event.fromJson(item as Map<String, dynamic>)).toList(), )); print('反序列化后的Map: $restoredEvents'); }
内容的提问来源于stack exchange,提问作者The Adam
相关产品推荐
相关产品推荐

