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

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,
            );

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.


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<String, String>]. 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});