Arduino fails to Post data to web api

I am trying to post the data i get from arduino, in an asp.net web api. Web api works fine when i test it with another client (in this case Fiddler). Arduino doesn't manage to make the connection with the controller of the web api. I don't get any error when i upload the code, just the connection isn't being done. Does anybody have any idea what could be going wrong? Is port 80 in client.print(server, 80) the right port?
Below is the code which makes the connection with the server :

if (client.connect(server, 80)) {
    client.print("POST /api/temp"); 
    client.print("Humidity="); 
    client.print(dht.humidity);
    client.print("&TemperatureC="); 
    client.print(dht.temperature_C);
    client.print("&TemperatureF="); 
    client.print(dht.temperature_F);
    client.print("&HeatindexC="); 
    client.print(heatindex1);
    client.print("&HeatindexF="); 
    client.print(heatindex2);
    client.print("&Max="); 
    client.print(max1);
    client.print("&Min="); 
    client.print(min1);
    client.println(" HTTP/1.1"); 
    client.println("Host: localhost:60550");
    client.println("Content-Type: application/json");
    client.println("Connection: close"); y line
    client.println(); // Empty line
    client.stop();

You're missing the question mark "?" after the /api/temp

That signals the start of your parameter list.

You are posting alot of information in the URL, you might want to put it in the BODY in JSON format. That could make it easier to parse for the server code. But both are fine. I'm not quite sure of the max length of the URL, so you might want to look that up. I do recommend using JSON in the body though.

I tried with the question mark and still not posting anything..
I don't have any clue on how to put it in the body of a JSON format but i will google it right now, thank you!! Maybe it will work because when i test it with Fiddler, the data i have is in the body of json format..

I also have another question, is port 80 the right port? Because my web api is listening on port 60550, but when i try client.print(server, 60550) arduino fails to connect, but it does make the connection with port 80, so i'm not getting the logic here

You are using a POST request with a GET format.

Ok, tried this now and still not working. I have written some values by myself for testing the connection. Now when i test the connection with the server, it fails to connect

char PostData[]="{\"Humidity\":\"4\",\"TemperatureC\":\"52\",\"TemperatureF\":\"35\",\"HeatIndexC\":\"53\",\"HeatIndexF\":\"54\",\"Max\":\"43\",\"Min\":\"75\"}";


if (client.connect(serverName, serverport)) { //where serverName=60550
 client.print("POST /api/temp HTTP/1.1");
  client.println("Host: http://localhost:60550");
  client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(strlen(PostData));
    client.println();
    client.println(PostData);
    client.println(); // Empty line
    client.stop();    // Closing connection to server

You should post all your code. If you are using localhost as the serverName to connect, it will fail.

Also, it should be client.print(PostData);, without the two new lines after the post data. (Otherwise, your content-length will be incorrect.)

Pieter

I am using localhost:60550, where 60550 is the port the iis server listens, and still not getting the posting parametres… Here is all the code…

#include "cactus_io_DHT22.h"
#include <SPI.h>
#include <Ethernet.h>
#include <Client.h>

#define DHT22_PIN 2

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xDD };
 
IPAddress ip(192,168,100,177);
IPAddress server(192,168,100,104);
EthernetClient client;
int serverport = 80;
char serverName = "192.168.100.104:60550";
DHT22 dht(DHT22_PIN);
float heatindex1 =0.00;
float heatindex2 = 0.00;
 

void setup() {
  Ethernet.begin(mac,ip);   
    delay(1000);  Serial.begin(9600); 

    Serial.println("connecting...");   
  Serial.print("Arduino server IP address: ");
  Serial.println(Ethernet.localIP());
  Serial.println("DHT22 Humidity - Temperature Sensor");
  Serial.println("RH\t\tTemp (C)\tTemp (F)\tHeat Index (C)\t Heat Index (F)\t Max(C)\t\t Min(C)");
 
  dht.begin();
  dht.readHumidity();
  dht.readTemperature();
  
}

float max1=dht.temperature_C;
 float min1=100;


void loop() {
  dht.readHumidity();
  dht.readTemperature();
  heatindex1=dht.computeHeatIndex_C();
  heatindex2=dht.computeHeatIndex_F();

 char PostData[]="{\"Humidity\":\"4\",\"TemperatureC\":\"452\",\"TemperatureF\":\"345\",\"HeatIndexC\":\"53\",\"HeatIndexF\":\"454\",\"Max\":\"433\",\"Min\":\"375\"}";
  if(dht.temperature_C>max1)
  {max1=dht.temperature_C;}
  if(dht.temperature_C<min1)
  {min1=dht.temperature_C;}
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(dht.humidity) || isnan(dht.temperature_C)) {
    Serial.println("DHT sensor read failure!");
    return;
  }
  if (client) {
    
    Serial.println("OK"); }

 if (client.connect(serverName, serverport)) {
 client.print("POST /api/temp HTTP/1.1");
  client.println("Host: http://localhost:60550");
  client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(strlen(PostData));
    client.println();
    client.println(PostData);
    client.stop();    

  }

  else {
    //If Arduino can't connect to the server (your computer or web page)
    Serial.println("--> connection failed\n");
  }

   Serial.print(dht.humidity); Serial.print(" %\t\t");
  Serial.print(dht.temperature_C); Serial.print(" *C\t");
  Serial.print(dht.temperature_F); Serial.print(" *F\t");
  Serial.print(dht.computeHeatIndex_C()); Serial.print(" *C\t ");
  Serial.print(dht.computeHeatIndex_F()); Serial.print(" *F\t ");
  Serial.print(max1); Serial.print(" *C\t ");
  Serial.print(min1); Serial.println(" *C\t");
 
  delay(10000);
}

esmeralda_h:
IPAddress server(192,168,100,104);
int serverport = 80;
char serverName = "192.168.100.104:60550

That doesn't make any sense.
If your server listens on port 60550, why do you try to connect to port 80?
"192.168.100.104:60550" is not a server name, it's an IP address and port number.

Try

IPAddress server(192,168,100,104);
int serverport = 60550;
...
client.connect(server, serverport)
...

That host header is wrong as well. It can't have 'http' in the header, and a server name of 'localhost' doesn't make any sense if it comes from an outside client.

Pieter

Tried

IPAddress server(192,168,100,104);
int serverport = 60550;
...
client.connect(server, serverport)
...

With host: localhost:60550
And in the Serial monitor i get connection failed
When i test sendind data to the web api with fiddler, as i have explained above, it works in this format:

When i change the port to 80, Arduino makes the connection and sends the data, but not on my server :frowning:

So, i made a research, and found out that since arduino itself is a machine trying to connect to a local web server, i had to configure the config file of the IIS Express (the one i’m using) for the web server. After making some configurations and adding a rule in the firewall so IIS allows arduino to make the connection, my code is as it follows:

#include "cactus_io_DHT22.h"
#include <SPI.h>
#include <Ethernet.h>
#include <Client.h>

#define DHT22_PIN 2

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xDD };
 
IPAddress ip(192,168,0,177);
IPAddress server(192,168,0,15);
EthernetClient client;

DHT22 dht(DHT22_PIN);
float heatindex1 =0.00;
float heatindex2 = 0.00;
 
void setup() {

  delay(1000);  
  Serial.begin(9600); 

  Serial.println("connecting...");   
  Serial.print("Arduino server IP address: ");
  Serial.println(Ethernet.localIP());
  Serial.println("DHT22 Humidity - Temperature Sensor");
  Serial.println("RH\t\tTemp (C)\tTemp (F)\tHeat Index (C)\t Heat Index (F)\t Max(C)\t\t Min(C)");
 
  dht.begin();
  dht.readHumidity();
  dht.readTemperature();
  
}

float max1=dht.temperature_C;
 float min1=100;
 struct KeyVal {
  const char *key;
  const char *val;
};

void loop() {
  dht.readHumidity();
  dht.readTemperature();
  heatindex1=dht.computeHeatIndex_C();
  heatindex2=dht.computeHeatIndex_F();

 char PostData[]="{\"Humidity\":\"4\",\"TemperatureC\":\"452\",\"TemperatureF\":\"345\",\"HeatIndexC\":\"53\",\"HeatIndexF\":\"454\",\"Max\":\"433\",\"Min\":\"375\"}";


  if(dht.temperature_C>max1)
  {max1=dht.temperature_C;}
  if(dht.temperature_C<min1)
  {min1=dht.temperature_C;}
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(dht.humidity) || isnan(dht.temperature_C)) {
    Serial.println("DHT sensor read failure!");
    return;
  }
  if (client) {
    
   // When a client sends a request to a webserver, that request ends with a blank line
    boolean currentLineIsBlank = true;
     
    Serial.println("OK"); }

 if (client.connect(server, 60550)) {
  Serial.println("Connected");
    client.print("POST /api/temp/postt HTTP/1.1");
    client.println("Host: 192.168.0.15");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(strlen(PostData));
    client.println();
    client.println(PostData);
    client.stop();    // Closing connection to server
  }

  else {
    //If Arduino can't connect to the server (your computer or web page)
    Serial.println("--> connection failed\n");
  }

   Serial.print(dht.humidity); Serial.print(" %\t\t");
  Serial.print(dht.temperature_C); Serial.print(" *C\t");
  Serial.print(dht.temperature_F); Serial.print(" *F\t");
  Serial.print(dht.computeHeatIndex_C()); Serial.print(" *C\t ");
  Serial.print(dht.computeHeatIndex_F()); Serial.print(" *F\t ");
  Serial.print(max1); Serial.print(" *C\t ");
  Serial.print(min1); Serial.println(" *C\t");
 
  delay(10000);
}

Now when i print Ethernet.localIP() i get 255.255.255.255 in the serial monitor. Is this even normal? And still Arduino can’t be connected to the server. This is driving me crazy, don’t know anymore what to do. Does anyone, who has experience on this, have any idea?

You forgot your Ethernet.begin(mac,ip) call.

Okay so i finally made it to make the connection and post the data successfully, if anyone will need it,i will post below the code. Now i need a little help with passing the real data to the web server, when i say the real data, i mean the one captured by arduino. I know i should pass them as parametres but i have no idea how.
The string i am currently passing is this: char PostData[]="{\"Humidity\":\"4\",\"TemperatureC\":\"52\",\"TemperatureF\":\"35\",\"HeatIndexC\":\"53\",\"HeatIndexF\":\"54\",\"Max\":\"43\",\"Min\":\"75\"}";

Is it supposed to be something like this ? : char PostData[]="{\"Humidity\":"dht.humidity",\"TemperatureC\":"dht.temperature_C",\"TemperatureF\":"dht.temperature_F",\"HeatIndexC\":"heatindex1",\"HeatIndexF\":"heatindex2",\"Max\":"max1",\"Min\":"min1"}";

Can anyone help me ?
Below is the working code with sample data

#include "cactus_io_DHT22.h"
#include <SPI.h>
#include <Ethernet.h>
#include <Client.h>

#define DHT22_PIN 2

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xDD };
 
IPAddress ip(192,168,0,177);
IPAddress server(192,168,0,15);
EthernetClient client;

DHT22 dht(DHT22_PIN);
float heatindex1 =0.00;
float heatindex2 = 0.00;
 

void setup() {

  delay(1000);  
  Serial.begin(9600); 
  Ethernet.begin(mac,ip);
  Serial.println("connecting...");   
  Serial.print("Arduino server IP address: ");
  Serial.println(Ethernet.localIP());
  Serial.println("DHT22 Humidity - Temperature Sensor");
  Serial.println("RH\t\tTemp (C)\tTemp (F)\tHeat Index (C)\t Heat Index (F)\t Max(C)\t\t Min(C)");
 
  dht.begin();
  dht.readHumidity();
  dht.readTemperature();
  
}

float max1=dht.temperature_C;
 float min1=100;

void loop() {
  dht.readHumidity();
  dht.readTemperature();
  heatindex1=dht.computeHeatIndex_C();
  heatindex2=dht.computeHeatIndex_F();

 char PostData[]="{\"Humidity\":\"4\",\"TemperatureC\":\"452\",\"TemperatureF\":\"345\",\"HeatIndexC\":\"53\",\"HeatIndexF\":\"454\",\"Max\":\"433\",\"Min\":\"375\"}";

  if(dht.temperature_C>max1)
  {max1=dht.temperature_C;}
  if(dht.temperature_C<min1)
  {min1=dht.temperature_C;}
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(dht.humidity) || isnan(dht.temperature_C)) {
    Serial.println("DHT sensor read failure!");
    return;
  }
  if (client) {
    
   // When a client sends a request to a webserver, that request ends with a blank line
    boolean currentLineIsBlank = true;
     
    Serial.println("OK"); }

 if (client.connect(server, 60550)) {
  Serial.println("Connected");
    client.println("POST /api/temp? HTTP/1.1");
    client.println("Host: 192.168.0.15:60550");
    client.println("User-Agent: arduino/1.8.3");
    
    client.println("Content-Type:  application/json");
    client.print("Content-Length: ");
    client.println(strlen(PostData));
    client.println("Connection: close");
    client.println();
    client.println(PostData);
    client.stop();    // Closing connection to server
}

  else {
    //If Arduino can't connect to the server (your computer or web page)
    Serial.println("--> connection failed\n");
  }

   Serial.print(dht.humidity); Serial.print(" %\t\t");
  Serial.print(dht.temperature_C); Serial.print(" *C\t");
  Serial.print(dht.temperature_F); Serial.print(" *F\t");
  Serial.print(dht.computeHeatIndex_C()); Serial.print(" *C\t ");
  Serial.print(dht.computeHeatIndex_F()); Serial.print(" *F\t ");
  Serial.print(max1); Serial.print(" *C\t ");
  Serial.print(min1); Serial.println(" *C\t");
 
  delay(10000);
}

Follow instruction - compile and run. The example shows you how to make the body of your html response (NOT THE HEADER). if you need help with the header - let me know. I haven't read the whole thread, so hopefully this is helpful. It demonstrates how to keep your variables integer in your JSON result, but also - as you requested provide them in string form.

I am trying to keep this simple readable. There are alot of ways to skin this cat, and a cool class the builds your full response, with header+body and cool addJson function may be preferable. But this will get the job done, and makes your code a little more readable. It also does NOT write to anything more than the console. So it is intended to demonstrate how to use the two Fmt functions and make your JSON pretty and readable.

See if this helps:
Make a new project - testJson.
Add a new tab onto your project. Call it FormatJSON.h
or just paste both code inserts into the main project, then remove the #include statement.
insert:

static String Fmt(String first, String second, bool last=false)
{
  String response;
  response = "\t\"" + first + "\":\"" + second + "\"";
  if (!last)
      response +=",";
  response +="\r\n";
  return response;
}

static String Fmt(String first, uint32_t second, bool last=false)
{
  String response;
  response = "\t\"" + first + "\":" + String(second);
  if (!last)
      response +=",";
  response +="\r\n";
  return response;
}

and in your main tab - make it look like this:

#include "FormatJson.h"
/* one of the desired formats, I also show an integer JSON result example
{
    "Humidity":"4",
    "TemperatureC":"52",
    "TemperatureF":"35",
    "HeatIndexC":"53",
    "HeatIndexF":"54",
    "Max":"43",
    "Min":"75"
}
*/    

#define LAST true
void setup() {
    Serial.begin(9600);
    delay(500);  
    uint32_t Humidity=4;
    uint32_t TemperatureC=52;
    uint32_t TemperatureF=35;
    uint32_t HeatIndexC=53;
    uint32_t HeatIndexF=54;
    uint32_t Max=43;
    uint32_t Min=75;
  
    Serial.println("First example shows a numeric Json result");
    String json="{\r\n";
    json+=Fmt("Humidity",     Humidity);
    json+=Fmt("TemperatureC", TemperatureC);
    json+=Fmt("TemperatureF", TemperatureF);
    json+=Fmt("HeatIndexC",   HeatIndexC);
    json+=Fmt("HeatIndexF",   HeatIndexF);
    json+=Fmt("Max",          Max);
    json+=Fmt("Min",          Min, LAST);
    json+="}\r\n";
    Serial.print(json);
    Serial.println("Second example shows a string Json result");
    json="{\r\n";
    json+=Fmt("Humidity",     String(Humidity));
    json+=Fmt("TemperatureC", String(TemperatureC));
    json+=Fmt("TemperatureF", String(TemperatureF));
    json+=Fmt("HeatIndexC",   String(HeatIndexC));
    json+=Fmt("HeatIndexF",   String(HeatIndexF));
    json+=Fmt("Max",          String(Max));
    json+=Fmt("Min",          String(Min),  LAST);
    json+="}\r\n";
    Serial.print(json);
}

void loop() {
}