title: Flutter: HttpClient post contentLength -- exception
body: <p>Very weird...</p>
  
  <p>In order to post some JSON data to my server, I define the contentLength to the length of the JSON encoded data but I then receive an exception that says "<em>Content size exceeds specified contentLength</em>".  Difference is 1 byte.</p>
  
  <p>Here is the source code:</p>
  
  <pre><code>Future&lt;Map&gt; ajaxPost(String serviceName, Map data) async {
    var responseBody = json.decode('{"data": "", "status": "NOK"}');
    try {
      var httpClient = new HttpClient();
      var uri = mid.serverHttps ? new Uri.https(mid.serverUrl, _serverApi + serviceName)
                                : new Uri.http(mid.serverUrl, _serverApi + serviceName);
      var request = await httpClient.postUrl(uri);
      var body = json.encode(data);
  
      request.headers
        ..add('X-mobile-uuid', await _getDeviceIdentity())
        ..add('X-mobile-token', await mid.getMobileToken());
  
      request.headers.contentLength = body.length;
      request.headers.set('Content-Type', 'application/json; charset=utf-8');
      request.write(body);
  
      var response = await request.close();
      if (response.statusCode == 200){
        responseBody = json.decode(await response.transform(utf8.decoder).join());
  
        //
        // If we receive a new token, let's save it
        //
        if (responseBody["status"] == "TOKEN"){
          await mid.setMobileToken(responseBody["data"]);
  
          // Let's change the status to "OK", to make it easier to handle
          responseBody["status"] = "OK";
        }
      }
    } catch(e){
      // An error was received
      throw new Exception("AJAX ERROR");
    }
    return responseBody;
  }
  </code></pre>
  
  <p>Some other times, it works fine...</p>
  
  <p>Am I doing anything wrong with this code?</p>
  
  <p>Many thanks for your help.</p>
  
  <p><strong>EDITED WITH SOLUTION</strong>:</p>
  
  <p>Many thanks for your help.  The simply fact of using <code>utf8.encode(json.encode(data))</code> did not fully work.  So, I turned to the <strong>http</strong> library and it now works like a charm.  The code is even lighter!</p>
  
  <p>Here is the new version of the code:</p>
  
  <pre><code>Future&lt;Map&gt; ajaxPut(String serviceName, Map data) async {
    var responseBody = json.decode('{"data": "", "status": "NOK"}');
    try {
      var response = await http.put(mid.urlBase + '/$_serverApi$serviceName',
          body: json.encode(data),
          headers: {
            'X-mobile-uuid': await _getDeviceIdentity(),
            'X-mobile-token': await mid.getMobileToken(),
            'Content-Type': 'application/json; charset=utf-8'
          });
  
      if (response.statusCode == 200) {
        responseBody = json.decode(response.body);
  
        //
        // If we receive a new token, let's save it
        //
        if (responseBody["status"] == "TOKEN") {
          await mid.setMobileToken(responseBody["data"]);
  
          // Let's change the status to "OK", to make it easier to handle
          responseBody["status"] = "OK";
        }
      }
    } catch (e) {
      // An error was received
      throw new Exception("AJAX ERROR");
    }
    return responseBody;
  }
  </code></pre>