JsonSerializable。无法将模型与 json 架构匹配

JsonSerializable. Can't match Model to json schema

以下 json 是 Google Place Details Api.

请求的响应正文
{
    "html_attributions": [],
    "result": {
        "address_components": [
            {
                "long_name": "18",
                "short_name": "18",
                "types": [
                    "street_number"
                ]
            },
            {
                "long_name": "Doiranis",
                "short_name": "Doiranis",
                "types": [
                    "route"
                ]
            },
            {
                "long_name": "Thessaloniki",
                "short_name": "Thessaloniki",
                "types": [
                    "locality",
                    "political"
                ]
            },
            {
                "long_name": "Thessaloniki",
                "short_name": "Thessaloniki",
                "types": [
                    "administrative_area_level_3",
                    "political"
                ]
            },
            {
                "long_name": "Greece",
                "short_name": "GR",
                "types": [
                    "country",
                    "political"
                ]
            },
            {
                "long_name": "546 39",
                "short_name": "546 39",
                "types": [
                    "postal_code"
                ]
            }
        ]
    },
    "status": "OK"
}

下面是我的Place模型class

import 'package:json_annotation/json_annotation.dart';

part 'place_model.g.dart';

@JsonSerializable(fieldRename: FieldRename.snake)
class Place {
  final String streetName;
  final String streetNumber;
  final String city;
  final String zipCode;

  Place({
    required this.streetName,
    required this.streetNumber,
    required this.city,
    required this.zipCode,
  });

  factory Place.fromJson(Map<String, dynamic> json) => _$PlaceFromJson(json);
}

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'place_model.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Place _$PlaceFromJson(Map<String, dynamic> json) => Place(
      streetName: json['street_name'] as String,
      streetNumber: json['street_number'] as String,
      city: json['city'] as String,
      zipCode: json['zip_code'] as String,
    );

Map<String, dynamic> _$PlaceToJson(Place instance) => <String, dynamic>{
      'street_name': instance.streetName,
      'street_number': instance.streetNumber,
      'city': instance.city,
      'zip_code': instance.zipCode,
    };

我的 Place 模型需要 address_components 列表中的 short_name 值,但是 目前我的模型与 json 架构不匹配。 我是一个没有经验的开发人员,这可能很简单。但是你能建议我一种正确生成 place_model.g.dart 的方法吗?

响应与您的目标不匹配class,因此您必须先转换它。

为响应创建模型:

@JsonSerializable()
class Response {
  final Result result;
  final String status;

  const Response({required this.result, required this.status});

  factory Response.fromJson(Map<String, dynamic> json) =>
      _$ResponseFromJson(json);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class Result {
  final List<AddressComponents> addressComponents;

  const Result({required this.addressComponents});

  factory Result.fromJson(Map<String, dynamic> json) => _$ResultFromJson(json);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class AddressComponents {
  final String longName;
  final String shortName;
  final List<String> types;

  const AddressComponents({
    required this.longName,
    required this.shortName,
    required this.types,
  });

  factory AddressComponents.fromJson(Map<String, dynamic> json) =>
      _$AddressComponentsFromJson(json);
}

现在您可以向 Place 模型添加一个工厂构造函数,它将从 Response:

构建一个 Place 模型
class Place {
  const Place({
    this.streetName,
    this.streetNumber,
    this.city,
    this.zipCode,
  });

  final String? streetName;
  final String? streetNumber;
  final String? city;
  final String? zipCode;

  factory Place.fromResponse(Response response) {
    final streetNumberComponent = response.result.addressComponents
        .where((c) => c.types.contains('street_number'));
    // .. here the rest of Place fields

    return Place(
      streetNumber: streetNumberComponent.isNotEmpty
          ? streetNumberComponent.first.shortName
          : null,
      // .. here the rest of Place fields
    );
  }
}