Flutter json_serializable构建失败

时间:2019-11-18 12:25:44

标签: flutter dart

我正在使用json_serializablejson_annotation,并为我的模型生成serialization/deserialization功能。但是,当我运行构建时,出现此错误。

  

运行JsonSerializableGenerator时出错   无法填充所需的构造函数参数:已创建。   包:explorer / models / Account / account.dart:46:3

它所指的行是我的模型构造函数。

Account(String id, String firstName, String lastName, String email,
  DateTime dob, DateTime created, DateTime updated,
  {String accessTkn, String refreshTkn}) {}

为什么会出现此错误?

根据要求,这是我的模型课。

import "package:json_annotation/json_annotation.dart";

part "account.g.dart";

@JsonSerializable(nullable: true)
class Account {
  @JsonKey(name: "id")
  String _id;

  @JsonKey(name: "first_name")
  String _firstName;

  @JsonKey(name: "last_name")
  String _lastName;

  @JsonKey(name: "email")
  String _email;

  @JsonKey(
      name: "dob", fromJson: _isoStringToDateTime, toJson: _dateTimeToIsoString)
  DateTime _dob;

  @JsonKey(
      name: "created",
      fromJson: _isoStringToDateTime,
      toJson: _dateTimeToIsoString)
  DateTime _created;

  @JsonKey(
      name: "updated",
      fromJson: _isoStringToDateTime,
      toJson: _dateTimeToIsoString)
  DateTime _updated;

  @JsonKey(name: "access_token")
  String _accessToken;

  @JsonKey(name: "refresh_token")
  String _refreshToken;

  Account(String id, String firstName, String lastName, String email,
      DateTime dob, DateTime created, DateTime updated,
      {String accessTkn, String refreshTkn}) {
    this._id = id;
    this._firstName = firstName;
    this._lastName = lastName;
    this._email = email;
    this._dob = dob;
    this._created = created;
    this._updated = updated;
    this._accessToken = accessToken;
    this._refreshToken = refreshTkn;
  }

  factory Account.fromJson(Map<String, dynamic> json) {
    _$AccountFromJson(json);
  }

  // converts a DateTime to a ISO string
  static String _dateTimeToIsoString(DateTime date) {
    return date.toIso8601String();
  }

  // convert back to date time
  static DateTime _isoStringToDateTime(String iso) {
    return DateTime.parse(iso);
  }

  /// get the account id
  String get id {
    return this._id;
  }

  /// get the account first name
  String get firstName {
    return this._firstName;
  }

  /// get the account last name
  String get lastName {
    return this._lastName;
  }

  /// get the account email.
  String get email {
    return this._email;
  }

  /// get the account owner's date of birth
  DateTime get dob {
   return this._dob;
  }

  /// Get the date the account was created.
  DateTime get createdAt {
    return this._created;
  }

  /// get teh date the account was last updated.
  DateTime get updatedAt {
   return this._updated;
  }

  // get the account access token.
  String get accessToken {
    return this._accessToken;
  }

  // get the account refresh token.
  String get refreshToken {
    return this._refreshToken;
  }

  /// clones the account instance
  Account clone() {
    return Account(this.id, this.firstName, this.lastName, this.email, this.dob,
        this.createdAt, this.updatedAt,
        accessTkn: this.accessToken, refreshTkn: this.refreshToken);
  }

  Map<String, dynamic> toJson() {
    _$AccountToJson(this);
  }
}

2 个答案:

答案 0 :(得分:1)

由于没有初始化传递的参数,而有一个空的构造函数,因此出现错误。

您必须初始化类中具有的每个参数,或者使用JsonSerializable(nullable: true)JsonKey(nullable: true)将它们允许为空

如果该解决方案不适合您,请共享您课程中的所有代码

编辑:

该库可以进行反射,我知道哪里出了错。

  1. 属性的名称应与您的参数相同。
  2. 您的吸气剂的名称应与您的参数相同

使用以下修复程序更改代码:

Account(String id, String firstName, String lastName, String email,
    DateTime dob, DateTime created, DateTime updated,
    String accessToken, String refreshToken) {
    this._id = id;
    this._firstName = firstName;
    this._lastName = lastName;
    this._email = email;
    this._dob = dob;
    this._created = created;
    this._updated = updated;
    this._accessToken = accessToken;
    this._refreshToken = refreshToken;
  }

  /// Get the date the account was created.
  DateTime get created {
    return this._created;
  }

  /// get teh date the account was last updated.
  DateTime get updated {
    return this._updated;
  }

答案 1 :(得分:0)

为便于将来参考,我想通过一个示例来说明上述问题,并提出一个通用的解决方案:

json_serializable + json_annotation使用构造函数参数名称作为json字段键。因此,以下两个示例之间有明显的区别:

@JsonSerializable()
class User {
  @JsonKey(name: "first_name") final String firstName;

  // In this case, the json key becomes 'first_name',
  // extracted from the explicitly referenced field annotation.
  const User(this.firstName);
}

@JsonSerializable()
class User {
  @JsonKey(name: "first_name") String _firstName;
  String get firstName => _firstName?.trim();

  // In this case, the json key becomes 'firstName',
  // extracted from the constructor parameter name. 
  // For reflection, the field and its annotation are not involved.
  User(String firstName) {
    this._firstName = firstName;
  }
}

我们要隐藏字段的原因有两个;我们不希望其他人能够更新其值,而是希望提供“校正”(在这种情况下为修整)的值,而不是提供从外部来源获取的未经验证的值。由于我们无法整齐地隐藏未验证的值,因此建议我们将其公开,但要明确指出其缺点,例如:

@JsonSerializable()
class User {
  // The field is final, so its value cannot be altered as if private.
  // It is exposed (sadly), but clearly mentions potential issues.
  @JsonKey(name: "first_name") final String firstNameUntrimmed;
  
  // This is the 'corrected' version available with a more pleasant field name.
  String get firstName => firstNameUntrimmed?.trim();

  const User(this.firstNameUntrimmed);
}