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

HttpDartFlutter

Http Problem Overview


Map<String,String> headers = {'Content-Type':'application/json','authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='};

var response = await post(Urls.getToken,
        headers: headers,
        body: {"grant_type":"password","username":"******","password":"*****","scope":"offline_access"},
      );

When I execute this I am unable to recieve data and the error thrown is

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

Http Solutions


Solution 1 - Http

You need to wrap the body in jsonEncode.

import 'package:http/http.dart' as http;
import 'dart:convert';

Map<String,String> headers = {'Content-Type':'application/json','authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='};
final msg = jsonEncode({"grant_type":"password","username":"******","password":"*****","scope":"offline_access"});

var response = await post(Urls.getToken,
               headers: headers,
               body: msg,
            );

Solution 2 - Http

Use jsonEncode to wrap your body object.

import 'package:http/http.dart' as http;
import 'dart:convert';

var headers = {
    'Content-Type':'application/json',
    'authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='
};

final body = {
    'username':'foo',
    'password':'pass123'
}

var response = await post(
    Urls.getToken,
    headers: headers,
    body: jsonEncode(body), // use jsonEncode()
);

Why jsonEncode?

body: It can be a HTML, JSON or XML, etc. This mean is we need to send/recive data in that perticular format. You can set this in content-type header its default value is text/plain.

As you set the content-type header to JSON you must have to pass a "valid" JSON as the body. But you are passing Map<String, String> as the body, which obviously throws an error.

So to solve this issue you need to change (or encode) your Map<String, String> data to JSON data.

Best way to do this is to use jsonEncode function.

Solution 3 - Http

had similar issue with http library...changed for dio 2.1.0 and the problem with headers is gone.

jsonEncode(body) didn't do the trick, because the docs say:

> Sends an HTTP POST request with the given headers and body to the given URL, which can be a [Uri] or a [String].

> [body] sets the body of the request. It can be a [String], a [List] or a [Map]. If it's a String, it's encoded using [encoding] and used as the body of the request. The content-type of the request will default to "text/plain".

> If [body] is a List, it's used as a list of bytes for the body of the request.

> If [body] is a Map, it's encoded as form fields using [encoding]. The content-type of the request will be set to "application/x-www-form-urlencoded"; this cannot be overridden. [encoding] defaults to [utf8].

> For more fine-grained control over the request, use [send] instead.

Future<Response> post(url, {Map<String, String> headers, body, Encoding encoding});

Solution 4 - Http

Map<String,String> header = {'Content-Type':'application/json-patch+json','accept':'application/json'};
    final msg = jsonEncode({"username":"$emailorPhoneN","password":"$passwrod"});

    try {
      var response = await http.post(UrlConstants.loginUrl, headers: header, body: msg,
      ).timeout(Duration(seconds: httpDuration));
      var convert = json.decode(response.body);
      print('**********Data from server $convert');

      if (convert == null) {
        return null;
      } else {
        String token = convert['token'];

        if (token != null) {
          SignUpModel signUpModel = SignUpModel.fromJson(convert);
          return signUpModel;
        } else {
          //*** GET Error message from the API provider.....
          SignUpModel signUpModel = SignUpModel.fromJson(convert);
          return signUpModel;
        }
      }

Solution 5 - Http

the exception is caused by incorrectly setting bodyFields. See: bodyFields

bodyFields is for form-encoded data, not JSON. For an example of how to POST JSON see: Write HTTP servers

So you're trying to pass a Map as the body. In this case it would assume that you are actually doing a application/x-www-form-urlencoded. What you need to do is encode the Map as a string and then do what you're doing.

Example

  Future<http.Response> patchAPICall(
      String url, Map param, String token) async {
    var responseJson;
    try {
      final response = await http.patch(Uri.parse(url),
          body: jsonEncode(param),
          headers: {
            "Authorization": token,
            "Content-Type": "application/json"
          }).timeout(const Duration(seconds: 60),
          onTimeout: () => throw TimeoutException(
              'The connection has timed out, Please try again!'));
      responseJson = response;
    } on SocketException {
      throw FetchDataException("You are not connected to internet");
    } on TimeoutException {
      print('Time out');
      throw TimeoutException("The connection has timed out, Please try again");
    }
    return responseJson;
  }

Solution 6 - Http

For me, jsonencode(body) did not work. This is worked for me instead:

body = json.encode(body);
http.post(Uri.parse(uri), headers: header, body: body);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFayazView Question on Stackoverflow
Solution 1 - HttpMonzaView Answer on Stackoverflow
Solution 2 - HttpRohit NishadView Answer on Stackoverflow
Solution 3 - HttpMattView Answer on Stackoverflow
Solution 4 - HttpSilenceCodderView Answer on Stackoverflow
Solution 5 - HttpParesh MangukiyaView Answer on Stackoverflow
Solution 6 - Httpseyhmus gumusView Answer on Stackoverflow