dart 如何从Flutter发送正文中的嵌套Json作为http post请求

neskvpey  于 2023-01-10  发布在  Flutter
关注(0)|答案(5)|浏览(374)

我正在尝试发送一个嵌套的Json作为我一直在工作的flutter应用程序中的一个http post请求的主体。

{
      "user" : {
        "UserName": "username",
        "password":"password",
        "Name": "name",
        "Email": "email"
      }
}

我尝试了很多方法,可以在网上找到这样做,但每次我得到一个500错误。下面是一个类转换成Json。

class SignupJson {
  String username;
  String email;
  String name;
  String password;

  SignupJson(this.email, this.name, this.password, this.username);

  Map toJson() =>{"user":{
    'UserName': username,
    'Name': name,
    'password': password,
    'Email': email
  }};

}

并将其传递给this以进行发布请求。(我放置了一个任意的url链接)

Future<int> attemptSignup ({String username, String password, String name, String email}) async {


    SignupJson data = SignupJson(username: username, password: password, name: name, email: email);
    var url = 'url';

    String body = jsonEncode(json);

    var res = await http.post(url,
    body: body);
    return res.statusCode;

  }
cvxl0en2

cvxl0en21#

添加如下标题:

Map<String, String> headers = {HttpHeaders.contentTypeHeader: "application/json"};

则在请求后:

var res = await http.post(url, headers: headers, body: body);
vqlkdk9b

vqlkdk9b2#

将Map定义为<String, dynamic>,例如:

Map<String, dynamic> data = {
"User": {
          "UserName":"username",
          "Password":"password"
    }
};

并在标题中添加以下内容:

HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('Accept', 'application/json');
request.headers.set('Content-type', 'application/json');
request.add(utf8.encode(json.encode(data)));
HttpClientResponse response = await request.close();
String reply = await utf8.decoder.bind(response).join();
httpClient.close();
iq3niunx

iq3niunx3#

我已经被这个问题困扰了20天了。下面是我如何克服这个问题的方法

Future<int> attemptSignup ({String username, String password, String name, String email}) async {

SignupJson data = SignupJson(username: username, password: password, name: name, email: email);
var url = 'url';

String body = jsonEncode(data);     

//here jsonEncode(data) return String bt in http body you are passing Map value

//So you have to convert String to Map
Map bodyMap = jsonDecode(body);         

// your nested json data
var bodyData = {       // where var store <String, dynamic> data as your demand
      "user" : bodyMap  
};

var res = await http.post(url,
body: bodyData,
headers: {"Content-Type": "application/json",},
);

return res.statusCode;

}

确保在http中添加标题

3zwjbxry

3zwjbxry4#

我根据这个json编写代码:

{
"user": {
    "UserName": "username",
    "password": "password",
    "Name": "name",
    "Email": "email"
  }
 }

您的Post API调用如下所示:

Future<User> postUser(String username, String password, String name, String 
 email) async {

 Paste your api url here
 String url = '';
   final response = await http.post(apiUrl, headers: {
   // Enter your headers parameter if needed
   //  E.g: 
   'Authorization' : 'xyz',
   'Content-Type' : 'application/json'
 },
 body: jsonEncode(<String, String>{
   'UserName' : username,
   'password' : password,
   'Name' : name,
   'Email' : email
  }));

 if (response.statusCode == 200) {
    var data = jsonDecode(response.body.toString());
    print(data);
    return User.fromJson(jsonDecode(response.body));
  } else {
   throw Exception('Failed to post user.');
  }
}

你的模特应该是:

class User {
     User? user;

     User({this.user});

     User.fromJson(Map<String, dynamic> json) {
       user = json['user'] != null ? new User.fromJson(json['user']) : null;
     }

    Map<String, dynamic> toJson() {
      final Map<String, dynamic> data = new Map<String, dynamic>();
      if (this.user != null) {
        data['user'] = this.user!.toJson();
      }
      return data;
     }
   }

  class User {
    String? userName;
    String? password;
    String? name;
    String? email;

      User({this.userName, this.password, this.name, this.email});

      User.fromJson(Map<String, dynamic> json) {
       userName = json['UserName'];
       password = json['password'];
       name = json['Name'];
       email = json['Email'];
     }

    Map<String, dynamic> toJson() {
       final Map<String, dynamic> data = new Map<String, dynamic>();
        data['UserName'] = this.userName;
        data['password'] = this.password;
        data['Name'] = this.name;
       data['Email'] = this.email;
      return data;
     }
    }
dauxcl2d

dauxcl2d5#

既然这个问题还没有答案,我就试试看。我和其他人花了同样的时间来解决这个问题,这是非常令人沮丧的。
What I learned is that the point of the content-type header is that it changes how Client.post structures the body as is creates the request, in addition to informing the server what type of data to expect. In my case, I had it erroneously set to 'application/x-www-form-urlencoded' which was working for other routes that I was passing individual maps of single-level objects and classes to, but it was failing on anything that had a key which had an object attached.
如果我试图通过Map上的关键,它赢得:

Expected a value of type 'String', but got one of type 'IdentityMap<String, dynamic>'.

当我正确地设置了头,但是传递了一个Map而不是json.encode 'edMap时,我得到了:

Bad state: Cannot set the body fields of a Request with content-type "application/json".

从Post函数的Dart文档中:
将具有给定标头和正文的HTTP POST请求发送到给定URL。
body设置请求的主体。它可以是一个字符串,一个列表或一个Map〈String,String〉。如果它是一个字符串,它使用编码进行编码,并用作请求的主体。请求的内容类型将默认为"text/plain"。
如果body是一个List,它将用作请求主体的字节列表。
如果body是Map,则使用encoding将其编码为表单字段,请求的内容类型将设置为"application/x-www-form-urlencoded";这不能被覆盖。
因此我们可以看到,如果content-type的特定头丢失,或者content-type被设置为application/json,并且向body传递了一个map,则map将导致post函数覆盖content-type头并将头设置为urlencoded。
因此,即使服务器不需要内容类型头,也可以说,它需要JSON编码的数据,实现这一点的唯一方法是:

  • 将内容类型标头设置为application/json AND
  • 使用相同的jsonEncode(map)或json.encode(map)传递正确的json编码的map(而不是普通的map)作为body参数。

相关问题