【问题标题】:Mapping JSON into Class Objects将 JSON 映射到类对象
【发布时间】:2017-12-24 15:35:46
【问题描述】:

我正在尝试将我的 JSON 文件映射到一个类对象,然后根据新收到的 JSON 更新卡片。

我的JSON结构是这样的

 {
        "$class": "FirstCard",
        "id": "1",
        "description": "I am card number one",
        "Role": "attack",
        "score": 0,
        "tag": [
            "string"
        ],................}

我的班级看起来像这样:

  class CardInfo {
  //Constructor
  String id;
  String description;
  String role;
  int score;

}

如何将 JSON 文件中的值映射到从 CardInfo 类创建的对象的字段中?

更新

以下试验在 ci.description 处打印 null,这是否意味着该对象从未创建?

const jsonCodec = const JsonCodec
_loadData() async {
  var url = 'myJsonURL';
  var httpClient  = createHttpClient();
  var response =await httpClient.get(url);
  print ("response" + response.body);
  Map cardInfo = jsonCodec.decode(response.body);
  var ci = new CardInfo.fromJson(cardInfo);
  print (ci.description); //prints null
}

更新2

打印 cardInfo 给出以下信息:

{$class: FirstCard, id: 1, description: 我是第一卡,........}

请注意,它类似于原始 JSON,但在字符串值上没有双引号。

【问题讨论】:

    标签: json dart flutter


    【解决方案1】:
    class CardInfo {
      //Constructor
      String id;
      String description;
      String role;
      int score;
    
      CardInfo.fromJson(Map json) {
        this.id = json['id'];
        this.description = json['description'];
        this.role = json['Role'];
        this.score = json['score'];
      }
    }
    
    var ci = new CardInfo.fromJson(myJson); 
    

    您可以使用https://github.com/dart-lang/source_genhttps://pub.dartlang.org/packages/json_serializable等源代码生成工具为您生成序列化和反序列化代码。

    如果您更喜欢使用不可变类,https://pub.dartlang.org/packages/built_value 是一个不错的选择。

    【讨论】:

    • 请检查我帖子中的更新部分,我尝试在对象 ci 中打印一个字段,但我得到的只是空。
    • print(cardInfo); 打印什么?
    • 它正在工作,我在映射到 JSON 值的键中有一个小错字,非常感谢你帮助我!
    【解决方案2】:

    如果您想从 url 获取 JSON,请执行以下操作:

    import 'dart:convert';
    
    _toObject() async {
      var url = 'YourJSONurl';
      var httpClient  = createHttpClient();
      var response =await httpClient.get(url);
      Map cardInfo = JSON.decode(response.body);
      var ci = new CardInfo.fromJson(cardInfo);
    }
    

    如果您想知道如何设置您的类以便可以将您的 JSON 字段映射到它,请参考主要答案。很有帮助。

    【讨论】:

      【解决方案3】:

      我为此使用名为 json_parser 的反射创建了一些有用的库,可在 pub 获得。

      https://github.com/gi097/json_parser

      您可以将以下内容添加到您的dependencies.yaml

      dependencies:
        json_parser: 0.1.1
        build_runner: 0.8.3
      

      然后可以使用以下方式解析json:

      DataClass instance = JsonParser.parseJson<DataClass>(json);
      

      关注README.md 了解更多说明。

      【讨论】:

      • 它是否适用于 dart 2.0?当前的 Dart SDK 版本是 2.1.0-dev.1.0.flutter-ccb16f7282。
      • 如果您使用的是最新版本,那么可以! :)
      • 错误:依赖于 json_parser >=0.0.2 =1.19.0
      • 使用json_parser: ^0.1.6
      • 同样的错误:因为 json_parser >=0.1.4 依赖于 build_runner ^0.10.1+1 而 App 依赖于 build_runner 0.8.3,所以 json_parser >=0.1.4 是被禁止的。所以,因为App依赖json_parser ^0.1.6,所以版本解析失败。
      【解决方案4】:

      我找到的最佳解决方案是this medium post

      这很容易将 Json 转换为飞镖

      import 'package:json_annotation/json_annotation.dart';
      
      part 'post_model.g.dart';
      
      @JsonSerializable()
      class PostModel {
        int userId;
        int id;
        String title;
        String body;
        PostModel(this.userId, this.id, this.title, this.body);
        factory PostModel.fromJson(Map<String, dynamic> json) => _$PostModelFromJson(json);
        Map<String, dynamic> toJson() => _$PostModelToJson(this);
      }
      

      【讨论】:

        【解决方案5】:

        此 pkg 可以帮助您将 JSON 转换为类实例。 https://www.npmjs.com/package/class-converter

        import { property, toClass } from 'class-convert';
        
        class UserModel {
          @property('i')
          id: number;
        
          @property()
          name: string;
        }
        
        const userRaw = {
          i: 1234,
          name: 'name',
        };
        
        // use toClass to convert plain object to class
        const userModel = toClass(userRaw, UserModel);
        // you will get a class, just like below one
        {
          id: 1234,
          name: 'name',
        }
        

        【讨论】:

          【解决方案6】:

          如果您不想手动创建它们,可以生成它们。

          pubspec.yaml添加依赖:

          dependencies:
            json_annotation: ^4.0.0
          dev_dependencies:
            build_it: ^0.2.5
            json_serializable: ^4.0.2
          

          创建配置文件my_classes.yaml:

          ---
          format:
            name: build_it
            generator:
              name: build_it:json
          ---
          
          checkNullSafety: true
          
          classes:
          - name: CardInfo
            fields:
            - { name: id, type: String? }
            - { name: description, type: String? }
            - { name: role, type: String?, jsonKey: { name: Role } }
            - { name: score, type: int? }
            - { name: tag, type: List<String>, jsonKey: { defaultValue: [] } }
          

          运行构建过程:

          dart run build_runner build
          

          生成代码my_classes.g.dart:

          // GENERATED CODE - DO NOT MODIFY BY HAND
          
          import 'package:json_annotation/json_annotation.dart';
          
          part 'my_classes.g.g.dart';
          
          // **************************************************************************
          // build_it: build_it:json
          // **************************************************************************
          
          @JsonSerializable()
          class CardInfo {
            CardInfo(
                {this.id, this.description, this.role, this.score, required this.tag});
          
            /// Creates an instance of 'CardInfo' from a JSON representation
            factory CardInfo.fromJson(Map<String, dynamic> json) =>
                _$CardInfoFromJson(json);
          
            String? id;
          
            String? description;
          
            @JsonKey(name: 'Role')
            String? role;
          
            int? score;
          
            @JsonKey(defaultValue: [])
            List<String> tag;
          
            /// Returns a JSON representation of the 'CardInfo' instance.
            Map<String, dynamic> toJson() => _$CardInfoToJson(this);
          }
          
          

          现在你可以使用它们了。

          【讨论】:

            猜你喜欢
            • 2019-05-27
            • 1970-01-01
            • 2012-04-23
            • 2015-06-27
            • 2013-06-16
            • 1970-01-01
            • 1970-01-01
            • 2014-11-07
            • 1970-01-01
            相关资源
            最近更新 更多