如何将嵌套JSON转换为对象

如何将嵌套JSON转换为对象,json,dart,flutter,Json,Dart,Flutter,我需要向Post请求发送一个对象作为主体参数。我的对象是从嵌套的Json创建的,到目前为止我还不能让它工作 我在JavaScript中很容易做到这一点,但在Dart/Flatter中还没有找到实现这一点的方法 我以前使用的“传统”方法非常简单: var data = { "email": "qwe@qwe.com", "password": "123", "first_name": "qweqwe", "billing": { "e

我需要向Post请求发送一个对象作为主体参数。我的对象是从嵌套的Json创建的,到目前为止我还不能让它工作

我在JavaScript中很容易做到这一点,但在Dart/Flatter中还没有找到实现这一点的方法

我以前使用的“传统”方法非常简单:

var data = {
      "email": "qwe@qwe.com",
      "password": "123",
      "first_name": "qweqwe",
      "billing": {
        "email": "qwe@qwe.com",
        "phone": "321654978",
      },
      "shipping": {
        "first_name": "qweqwe",
      }
    }
通过在省道/颤振中使用相同的结构,我得到以下误差

[错误:flatter/lib/ui/ui\u dart\u state.cc(148)]未处理的异常:类型“\u InternalLinkedHashMap”不是类型转换中“String”类型的子类型

我已经尝试了
Map
Map
,使用了我的数据模型


如果我发送相同的Json,但没有
“billing”
“shipping”
(没有嵌套的Json),它就可以工作。

在Json中,值之间应该只有逗号

var data = {
  "email": "qwe@qwe.com",
  "password": "123",
  "first_name": "qweqwe",
  "billing": {
    "email": "qwe@qwe.com",
    "phone": "321654978"
  },
  "shipping": {
    "first_name": "qweqwe"
  }
}

在这里,我删除了字段“phone”和“first_name”末尾的逗号

如果要上载
数据
对象,排序答案是将其转换为如下所示的字符串:

var jsonString = json.encode(data);
// upload jsonString as body to your server.
print("Json String is " + jsonString);

Map headers = {
  'Content-type' : 'application/json',
};

http.post("www.server.com/myPostEndpoint", body: jsonString, headers: headers);
var data = {
  "email": "qwe@qwe.com",
  "password": "123",
  "first_name": "qweqwe",
  "billing": {
    "email": "qwe@qwe.com",
    "phone": "321654978",
  },
  "shipping": {
    "first_name": "qweqwe",
  }
};


var user = User.fromJson(data);

print("Users Email is ${user.billing["email"]}");
正如在注释中所讨论的,您可能需要将整个内容包装在
data
属性中。你可以试试这个:

var payload = {   
    "data": {
       "email": "qwe@qwe.com",
       "password": "123",
       "first_name": "qweqwe",
       "billing": {
         "email": "qwe@qwe.com",
         "phone": "321654978",
       },
       "shipping": {
         "first_name": "qweqwe",
       }   
   } 
};

var jsonString = json.encode(payload); // upload jsonString as body to your server. print("Json String is " + jsonString);

Map headers = {   'Content-type': 'application/json', };

http.post("www.server.com/myPostEndpoint", body: jsonString, headers: headers);
tl;dr

创建一个模型总是一个好主意。 因此,这可能是您的
用户
模型:

class User {
  final String email;
  final String password;
  final String firstName;
  final Map<String, String> billing;
  final Map<String, String> shipping;

  User({this.email, this.password, this.firstName, this.billing, this.shipping});

  static User fromJson(dynamic json) {
    return User(
      email: json["email"],
      password: json["password"],
      firstName: json["first_name"],
      billing: json["billing"],
      shipping: json["shipping"],
    );
  }

}
计费
和可能的
发货
创建模型会更干净

下面是一个完整的示例,其中还包括从解析模型生成Json的
toJson()
方法:

class User {
  final String email;
  final String password;
  final String firstName;
  final Billing billing;
  final Shipping shipping;

  User({this.email, this.password, this.firstName, this.billing, this.shipping});

  static User fromJson(dynamic json) {
    return User(
      email: json["email"],
      password: json["password"],
      firstName: json["first_name"],
      billing: Billing.fromJson(json["billing"]),
      shipping: Shipping.fromJson(json["shipping"]),
    );
  }

  Map<String, dynamic> toJson() => {'email': email, 'password': password, 'first_name': firstName, 'billing': billing.toJson(), 'shipping': shipping.toJson()};
}

class Billing {
  final String email;
  final String phone;

  Billing({this.email, this.phone});

  static Billing fromJson(dynamic json) {
    return Billing(email: json["email"], phone: json["phone"]);
  }

  Map<String, dynamic> toJson() => {'email': email, 'phone': phone};
}

class Shipping {
  final String name;

  Shipping({
    this.name,
  });

  static Shipping fromJson(dynamic json) {
    return Shipping(
      name: json["first_name"],
    );
  }


  Map<String, dynamic> toJson() => {'name': name};
}

我认为其他答案可能(很大程度上)过于复杂化了。无论使用哪种语言,要将JSON发送到服务器,都需要将数据作为字符串发送,并使用
application/JSON
内容类型
json.encode
已经处理了嵌套映射,所以您不需要做任何特殊的事情。。。总之:

//将“…”替换为其余数据。
var数据={“电子邮件”:qwe@qwe.com“,”密码“:“123”,…}
//`asJson`是一个字符串。
var asJson=json.encode(数据);
//发送它
var response=await client.post('example.com/…',body:asJson,headers:{'content-type','application/json'});
这就是你需要做的。实际上不需要使用
fromJson
toJson
等创建一个完整的
User


对于此错误-
未处理的异常:类型“\u InternalLinkedHashMap”不是类型转换中“String”类型的子类型
,我不知道确切的原因是什么,因为您没有提供相关的代码,但很明显,在某个时候,您给了Dart一个映射,其中它需要字符串。正如您所说,您已经尝试了
Map
Map问题的可能重复很可能与来回转换JSON无关。这似乎更像是服务器不接受的错误有效负载结构。当我使用模型作为参数时,我会得到
无效的请求主体“User”实例
我需要的是能够将对象作为主体参数发送,而不仅仅是解析它。。。我在这件事上耽搁了几天。。。我现在不知道如何将它用作参数?在我的问题中,我需要它来发送“转换”的Json作为Http Post请求的参数。哦,是的,我很抱歉。一定是误解了你的问题。请看一下我的编辑。现在它已经为你的帖子正文生成了一个json字符串。也许这就是你要寻找的。你说的“失败”是什么意思?您是否收到运行时错误,或者服务器本身是否向您发送了错误?如果你不说。。。
var data = {
  "email": "qwe@qwe.com",
  "password": "123",
  "first_name": "qweqwe",
  "billing": {
    "email": "qwe@qwe.com",
    "phone": "321654978",
  },
  "shipping": {
    "first_name": "qweqwe",
  }
};


var user = User.fromJson(data);

print("Users Email is ${user.billing.email}");
print("Shipping name is ${user.shipping.name}");

var jsonString = json.encode(user.toJson()); // upload this as body to your server.
print("Json String is " + jsonString);