Сериализация Flutter JSON - файлы *.g.dart не создаются

Я новичок в флаттере, и цель состоит в том, чтобы сериализовать сложные объекты JSON, содержащие другие более мелкие объекты.

Используя json_serializable: ^2.0.0 и pubspec.yaml файл выглядит примерно так.

dependencies:
  intl: ^0.15.7
  json_annotation: ^2.0.0
  built_value: ^6.7.1
  flutter:
    sdk: flutter

dev_dependencies:
  build_runner: ^1.0.0
  json_serializable: ^2.0.0
  built_value_generator: ^6.7.1
  flutter_test:
    sdk: flutter

В user.dart выглядеть так

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable(nullable: false)
class User {
  final String firstName;
  final String lastName;
  final DateTime dateOfBirth;
  User({this.firstName, this.lastName, this.dateOfBirth});
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

я пытался flutter pub run build_runner build но файл user.g.dart не создается, и я столкнулся с проблемой.

Я также добавил build.yaml файл со следующим кодом

targets:
  $default:
    builders:
      built_value_generator|built_value:
        generate_for:
          - model/*.dart
      json_serializable|json_serializable:
        generate_for:
          - model/*.dart

Может ли кто-нибудь сообщить мне, что мне здесь не хватает. Спасибо

14 ответов

Решение

Аргумент конструктора не должен быть необязательным

User({this.firstName, this.lastName, this.dateOfBirth});

Они должны быть обязательными:

User(this.firstName, this.lastName, this.dateOfBirth);

И часть

'user.g.dart';

должен соответствовать классу Uppercase User:

part 'User.g.dart';

Контрольный список

  • ваши файлы классов находятся под /lib или /bin
    • могут быть подкаталогами в этих
    • json_serializable не будет искать файлы для создания в каждом каталоге.
  • вы добавили part директива после import заявления
    • ваш partфайл с именем после вашего класса файла (а не имя класса самого), сg добавлено
    • например, для CacheItem класс с...
    • cache-item.dart имя файла класса...
    • part 'cache-item.g.dart'; получает соответствующий part директива.
    • то part Директива названа не в честь вашего фактического класса, а в честь имени файла класса.
  • вы добавили @JsonSerializable() над названием класса
  • вы создали конструктор по умолчанию для своего класса.
    • Он может быть пустым, иметь необязательные именованные параметры или позиционные параметры.
    • Пока поля вашего класса доступны (либо через конструктор, либо через общедоступные сеттеры и геттеры), json_serializable может справиться с этим. (т.е. не иметь только свойств _private и пустого конструктора)
  • вы написали методы-заглушки:
    • factory <Class>.fromJson(json) => _$ClassFromJson(json);
    • toJson() => _$ClassToJson(this)
    • методы-заглушки являются частными (начинаются с _ нижнее подчеркивание)
    • методы $tub имеют $
    • методы-заглушки имеют правильный CaSe (т.е. регистр Паскаля)
    • заглушка factory поставки (Map<String,dynamic> json) как аргумент
    • заглушка toJson() возвращается Map<String,dynamic>

Когда все будет готово, попробуйте запустить генератор из корневого каталога проекта...

Во флаттере:

flutter pub run build_runner build

В чистом дротике:

pub run build_runner build

Пример проекта на github, соответствующие файлы в /bin/ и пакеты в pubspec.yaml

Справочные материалы и документы

пример

import 'package:json_annotation/json_annotation.dart';

part 'cache-item.g.dart';

@JsonSerializable()
class CacheItem {
  int created;
  String keywords;
  String response;

  CacheItem(this.created, this.keywords, this.response);

  factory CacheItem.fromJson(Map<String,dynamic> json) => _$CacheItemFromJson(json);
  Map<String,dynamic> toJson() => _$CacheItemToJson(this);
}

Выход

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'cache-item.dart';

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

CacheItem _$CacheItemFromJson(Map<String, dynamic> json) {
  return CacheItem(
    json['created'] as int,
    json['keywords'] as String,
    json['response'] as String,
  );
}

Map<String, dynamic> _$CacheItemToJson(CacheItem instance) => <String, dynamic>{
      'created': instance.created,
      'keywords': instance.keywords,
      'response': instance.response,
    };


Пример варианта конструктора

Этот пример такой же, как и выше, за исключением того, что в конструкторе отсутствуют некоторые поля и есть response как необязательный.

Это замечательно.

Генератор будет просто использовать общедоступные (неявные) геттеры после создания экземпляра объекта для присвоения значений.

import 'package:json_annotation/json_annotation.dart';

part 'cache-item.g.dart';

@JsonSerializable()
class CacheItem {
  int created;
  String keywords;
  String response;

  CacheItem({this.response});

  factory CacheItem.fromJson(Map<String,dynamic> json) => _$CacheItemFromJson(json);
  Map<String,dynamic> toJson() => _$CacheItemToJson(this);
}

Выход

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'cache-item.dart';

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

CacheItem _$CacheItemFromJson(Map<String, dynamic> json) {
  return CacheItem(
    response: json['response'] as String,
  )
    ..created = json['created'] as int
    ..keywords = json['keywords'] as String;
}

Map<String, dynamic> _$CacheItemToJson(CacheItem instance) => <String, dynamic>{
      'created': instance.created,
      'keywords': instance.keywords,
      'response': instance.response,
    };

попробуйте бежать

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

Если вы пытаетесь сгенерировать файлы .g, просто запустив команду, и вы не получаете желаемого результата, просто попробуйте:

  1. flutter clean

  2. «восстановление кеша флаттер-паба»

  3. flutter packages pub run build_runner build --delete-conflicting-outputs

  4. удалить все временные файлы Gradle

  5. затем беги flutter pub get

  6. flutter packages pub run build_runner build.

Я столкнулся с той же проблемой и попробовал все упомянутые выше предложения, но ничего не помогло. После нескольких часов борьбы, я узнал, что файл должен быть сохранен перед запуском команды.

  • пакеты флаттера pub run build_runner build

Я знаю, что ответ такой простой, но вы сохранили файл перед запуском команды

Имя файла, класс и part 'Book.g.dart'; все должно совпадать.

добавление

      json_serializable: ^6.0.0

to dev_dependencies решить это для меня

в моем случае мне пришлось добавить пакет hive_generator вместе с пакетом build_runner. Если имя класса вашей модели, например, transaction.dart, то оно будет таким: part 'transaction.g.dart'Запустите команду- flutter packages pub run build_runner buildон сгенерирует для вас модель транзакции.

У меня была следующая ошибка

ошибка

[WARNING] json_serializable:json_serializable on lib/day10/models/sentence.dart:
Missing "part 'sentence.g.dart';".

Я заметил, что мне пришлось изменить в файле модели это part 'Sentence.g.dart'; к этому part 'sentence.g.dart'; другими словами, мне нужно было записать его в нижний регистр.

пожалуйста, проверьте свой part file name, например:
если имя вашего файла dartuser_model.dart, ваша часть «xxx.g.dart» должна быть:

      part 'user_model.g.dart'

это сработало для моего проекта. Для меня после части xxx.g.dart должно быть имя файла .dart, а не имя класса.

В моем случае проблема заключалась в том, что я неправильно написал имя метода. Я написал formJson вместо fromJson.

      factory MyClass.formJson(Map<String, dynamic> json) =>
_$MyClassFromJson(json);

должно было :

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

Несколько раз мы забывали сохранить файлы, пожалуйста, сохраните файл, а затем запустите команду.

      flutter packages pub run build_runner build

Шаг 1: Добавьте «часть 'your_class_name.g.dart'»

Шаг 2: Запустите эту команду в терминале: flutter pub run build_runner build

Пример:

      part 'student.g.dart'

@JsonSerializable()
class Student{
....
}

Не забудьте сохранить файл с расширениемclass даже если он все еще имеет ошибки

Затем запустите команду на любом терминале (или встроенном терминале)...

Но для Дарта:

      pub run build_runner build

И для флаттера:

      flutter pub run build_runner build

Официальная справочная ссылка:

Другие вопросы по тегам