【问题标题】:JSON encoding in DartDart 中的 JSON 编码
【发布时间】:2021-01-21 20:10:17
【问题描述】:

我曾在 Flutter/Dart 应用程序中对 JSON 进行解码/编码。解码工作得很好,但是在将我的对象编码为 JSON 时我遇到了一个非常讨厌的问题。

这些是嵌套对象。他们每个人都有自己的 toJson 和 fromJson 方法,以确保 jsonEncode 和 Decode 工作。我工作的一个小sn-p:

class App {
  factory App.fromJson(Map<String, dynamic> json) => App(
        langPref: json["langPref"],
        langFallb: json["langFallb"],
        users: List.of(json["users"]).map((i) => i).toList(),
      );

  String langPref;
  String langFallb;
  List<User> users;

  /// JSON-Export
  Map<String, dynamic> toJson() => {
        "langPref": langPref,
        "langFallb": langFallb,
        "users": jsonEncode(users),
      };
}

和嵌套类:

class User {
  int userid;
// actually there's more, including more nested objects


  /// JSON-Import
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      userid: int.parse(json["userid"]),
    );
  }

  /// JSON-Export
  Map<String, dynamic> toJson() {
    return {
      "userid": this.userid,
    };
  }
}

问题是:当我对顶级类“App”进行编码时,它正确地调用了嵌套类的 toJson() 方法。但是,对应的 JSON 应该是这样的:

{
    "langPref":"de-DE",
    "langFallb":"en-GB",
    "users":
        [
            {
                "userid": 1
// and so on

然而,它看起来像这样:

{
    "langPref":"de-DE",
    "langFallb":"en-GB",
    "users":"[{\"userid\":1
// and so on

所以,jsonEncode 不知何故引入了额外的双引号,这在某种程度上甚至是有意义的。它产生一个字符串,并且在 JSON 中应该对一个字符串进行编码....但是我猜我只是做错了什么并且遗漏了一些明显的东西....我怎样才能告诉 jsonEncode 接受操作的结果,而不是将其编码为字符串?

有人可以帮帮我吗?

【问题讨论】:

    标签: json flutter dart


    【解决方案1】:

    太好了....我会回答我自己的问题。 :-)

    进一步的实验得出以下结论:

    class App {
      factory App.fromJson(Map<String, dynamic> json) => App(
            langPref: json["langPref"],
            langFallb: json["langFallb"],
            users: List.of(json["users"]).map((i) => i).toList(),
          );
    
      String langPref;
      String langFallb;
      List<User> users;
    
      /// JSON-Export
      Map<String, dynamic> toJson() => {
            "langPref": langPref,
            "langFallb": langFallb,
            "users": users,
          };
    }
    

    New 只是最后一行...。我可以直接传递用户列表。没有必要对所有嵌套对象、列表和映射等使用 jsonEncode。

    很抱歉偷走了读者的时间,但也许这个答案会对其他人有所帮助。

    【讨论】:

      【解决方案2】:

      这个问题出现是因为你使用了jsonEncode(),它返回了字符串对象

      您必须使用返回 MapjsonDecode() 你的 App 类将如下所示

      class App {
        factory App.fromJson(Map<String, dynamic> json) => App(
              langPref: json["langPref"],
              langFallb: json["langFallb"],
              users: List.of(json["users"]).map((i) => i).toList(),
            );
      
        String langPref;
        String langFallb;
        List<User> users;
      
        /// JSON-Export
        Map<String, dynamic> toJson() => {
              "langPref": langPref,
              "langFallb": langFallb,
              "users": jsonEDecode(users),
            };
      }
      

      更新

      第二种方法是删除jsonEncode()而不使用jsonDecode()

      第三种方法在用户类中使用tojson()方法,如下代码

      "users": users.map((user) => user.tojson()).toList(),
      

      第四种方法 最好的方法 使用 json_serializable 库和 json_annotation 库为带注释的类生成 json 序列化, Flutter 团队批准此方法为最佳方法,官方方法见 Official Flutter Documentation

      app.dart

      import 'package:json_annotation/json_annotation.dart';
      
      part 'app.g.dart';
      
      @JsonSerializable()
      class App{
        String langPref;
        String langFallb;
        List<User> users;
        
        App({this.langPref, this.langFallb, this.users});
      
        factory App.fromJson(Map<String, dynamic> json) => _$AppFromJson(json);
      
        Map<String, dynamic> toJson() => _$AppToJson(this);
      
      }
      

      user.dart

      import 'package:json_annotation/json_annotation.dart';
      
      part 'user.g.dart';
      
      @JsonSerializable()
      class User{
        int userId;
        
        User({this.userId});
      
        factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
      
        Map<String, dynamic> toJson() => _$UserToJson(this);
      }
      

      【讨论】:

      • 首先感谢您的回答....嗯,更好的jsonDecode,就像您提出的那样,还是直接扔给用户? .... 它适用于我的测试用例,但也许您的解决方案更安全?
      • 我用其他 3 种方法更新了我的答案 json 序列化的最佳方法是第 4 种方法
      猜你喜欢
      • 2022-01-09
      • 2021-01-25
      • 2015-07-31
      • 1970-01-01
      • 2021-10-13
      • 2015-10-01
      • 1970-01-01
      • 2020-04-25
      • 2019-05-19
      相关资源
      最近更新 更多