扑 json_serializable: fromJson returns 空

Flutter json_serializable: fromJson returns null

我从 api 收到的 json 看起来像这样:

{
  "USD": [
    {
      "name": "something",
      "value": 123
    },
    {
      "name": "something else",
      "value": 1234
    }
  ],
  "EUR": [
    ... same here
  ]
}

我的飞镖模型看起来像:

@JsonSerializable(anyMap: true, includeIfNull: true)
class StatisticsDto {
  StatisticsDto({this.statistics});

  final Map<String, List<StatisticsDetailDto>> statistics;

  factory StatisticsDto.fromJson(Map<String, dynamic> json) =>
      _$StatisticsDtoFromJson(json);

  Map<String, dynamic> toJson() => _$StatisticsDtoToJson(this);
}

@JsonSerializable()
class StatisticsDetailDto {
  StatisticsDetailDto({
    this.name,
    this.value,
  });

  final String name;
  final num value;

  factory StatisticsDetailDto.fromJson(Map<String, dynamic> json) =>
      _$StatisticsDetailDtoFromJson(json);

  Map<String, dynamic> toJson() => _$StatisticsDetailDtoToJson(this);
}

我似乎无法让它工作,我从 api 中得到了一个 200,但是序列化 returns 为空。

我做错了什么?

这就是你的 JSON 对象转换为 Dart 数据 class 和 json_serializable

的样子
{
    "USD": [{
            "name": "something",
            "value": 123
        },
        {
            "name": "something else",
            "value": 1234
        }
    ],
    "EUR": [{
            "name": "something",
            "value": 123
        },
        {
            "name": "something else",
            "value": 1234
        }
    ]
}

Dart 数据 class 有 json_serializable 没有 Map 支持:

import 'package:json_annotation/json_annotation.dart';

part 'statistic_dto.g.dart';
part 'currency.g.dart';

@JsonSerializable()
class StatisticDto {
  StatisticDto({this.usd, this.eur});

  @JsonKey(name: 'USD')
  List<Currency>? usd;
  @JsonKey(name: 'EUR')
  List<Currency>? eur;

  factory StatisticDto.fromJson(Map<String, dynamic> json) {
    return _$StatisticDtoFromJson(json);
  }

  Map<String, dynamic> toJson() => _$StatisticDtoToJson(this);
}

@JsonSerializable()
class Currency {
  Currency({this.name, this.value});

  String? name;
  int? value;

  factory Currency.fromJson(Map<String, dynamic> json) => _$CurrencyFromJson(json);

  Map<String, dynamic> toJson() => _$CurrencyToJson(this);
}

运行:

flutter pub run build_runner build --delete-conflicting-outputs

在您的第一个示例中,您的地图统计信息没有关键信息,因此它总是 returns 为空。 JSON 您的第一个 class 数据

文件看起来像这样
// For: final Map<String, Map<String, dynamic>> statistics;
{
    "statistics": {
        "USD": {
            "name": "One",
            "value": 1
        },
        "EUR": {
            "name": "Four",
            "value": 4
        }
    }
}

如果您希望使用固定键序列化 json,请参考 Arnas 的回答。

在我的例子中,json 有动态键,例如它是一个具有不定数量键(在我的例子中对应于货币代码)和对应值(对象数组)的映射。

现在,我认为 @JsonSerializable 不适合这种场景,因此我实现了自己的 .fromJson() 工厂。

class StatisticsDto {
  StatisticsDto({this.statistics});

  final Map<String, List<StatisticsDetailDto>> statistics;

  factory StatisticsDto.fromJson(Map<String, dynamic> json) =>
      StatisticsDto(
          statistics: json.map((String currency, dynamic details) {
              final List<StatisticsDetailDto> currencyDetails = details
                .map<StatisticsDetailDto>(
                    (detail) => StatisticsDetailDto.fromJson(detail))
                .toList();
            return MapEntry<String, List<StatisticsDetailDto>>(currency, currencyDetails);
          })
      );
}

class StatisticsDetailDto {
  StatisticsDetailDto({
    this.name,
    this.value,
  });

  final String name;
  final num value;

  factory StatisticsDetailDto.fromJson(Map<String, dynamic> json) =>
      StatisticsDetailDto(
          type: json['name'],
          value: json['value'],
      );
}