JSON HTTP Post...

 

Hi folks,


I'm trying to find a good example of posting JSON data in MQL4. Is there an easy way to do this?


Thanks in advance

 
  1. Why did you post your MT4 question in the Root / MT5 General section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum
    Next time post in the correct place. The moderators will likely move this thread there soon.

  2. If you have to ask, it will definitely not be easy.
 
whroeder1:
  1. Why did you post your MT4 question in the Root / MT5 General section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum
    Next time post in the correct place. The moderators will likely move this thread there soon.

  2. If you have to ask, it will definitely not be easy

So you don't know then

 
locactus:

I'm trying to find a good example of posting JSON data in MQL4. Is there an easy way to do this?

If you literally just need to send some JSON to a URL as the body of a POST request, then it's extremely simple:

   // JSON text to send
   string strJsonText = "{\"key\": \"value\"}";
   
   // Text must be converted to a uchar array. Note that StringToCharArray() adds 
   // a nul character to the end of the array unless the size/length parameter
   // is explicitly specified 
   uchar jsonData[];
   StringToCharArray(strJsonText, jsonData, 0, StringLen(strJsonText));

   // Use MT4's WebRequest() to send the JSON data to the server.
   char serverResult[];
   string serverHeaders;
   int res = WebRequest("POST", "http://myserver/mypage", "", "", 10000, jsonData, ArraySize(jsonData), serverResult, serverHeaders);

   Print("Web request result: ", res, ", error: #", (res == -1 ? GetLastError() : 0));

However, real-world requirements may be more complex. For example, a lot of server middleware which processes incoming JSON data imposes pedantic requirements such as explicitly setting the Content-Type on your request to something like text/json or application/json.

 
JC:

If you literally just need to send some JSON to a URL as the body of a POST request, then it's extremely simple:

However, real-world requirements may be more complex. For example, a lot of server middleware which processes incoming JSON data imposes pedantic requirements such as explicitly setting the Content-Type on your request to something like text/json or application/json.

Many Thanks JC. Many of the examples I saw used 3rd party libs to create the JSON and seemed a bit heavy weight. Nice and simple approach :) I'm in charge of the server so know all I need to do is set the Request Headers so shouldn't be an issue if WebRequest adds the serverHeaders.

Once again thanks for your help.

 
JC:

If you literally just need to send some JSON to a URL as the body of a POST request, then it's extremely simple:

However, real-world requirements may be more complex. For example, a lot of server middleware which processes incoming JSON data imposes pedantic requirements such as explicitly setting the Content-Type on your request to something like text/json or application/json.

can you help how can the parse this data {"respond":1,"paging":{"stillmore":0,"perpage":0,"callpage":0,"next":0,"previous":0,"pages":0,"result":0},"message":"","result":[{"user_id":"243","enddate":"2018-02-20 00:00:00","user_email":"teste@test.com","display_name":"Jonh Tester","status":"active"}]}


im only getting the respond = 1....  if i print resp i can get all data on mt4 log but when i try to get for example display_name comes nothing



string resp = httpGET("https://"+ip_adress+""+prefixPort);
  
   JSONParser *parser = new JSONParser();

    JSONValue *jv = parser.parse(resp);

    if (jv == NULL) {
        Print("error:"+(string)parser.getErrorCode()+parser.getErrorMessage());
    } else {


        Print("PARSED:"+jv.toString());
        
        if (jv.isObject()) { // check root value is an object. (it can be an array)

            JSONObject *jo = jv;

            // Direct access - will throw null pointer if wrong getter used.
           // Print("firstName:" + jo.getString("firstName"));
           // Print("city:" + jo.getObject("address").getString("city"));
            //Print("phone:" + jo.getArray("message").getObject(0).getString("number"));

            // Safe access in case JSON data is missing or different.
            //if (jo.getString("user_mail",resp) ) Print("User = "+resp);

            // Loop over object keys
            JSONIterator *it = new JSONIterator(jo);
            for( ; it.hasNext() ; it.next()) {
                Print("loop:"+it.key()+" = "+it.val().toString());
            }
            delete it;
        }
        delete jv;
    }
    delete parser;
 
sostrader:

can you help how can the parse this data ...

This is really a complete change of topic from what the OP asked... Nevertheless, assuming that you are using ydrol's JSON parser from https://www.mql5.com/en/code/11134, then you need to walk the tree of objects as illustrated by the following example:

   JSONParser *parser = new JSONParser();
   
   // Get root object
   JSONObject * root= parser.parse(resp);
   
   // Get paging:{} object within root object
   JSONObject * paging = root.getObject("paging");

   // Display value of paging.stillmode
   Print("Value of 'stillmore': " , paging.getInt("stillmore"));
   
   // Get array of result[] items
   JSONArray * arrResult = root.getArray("result");
   Print("Number of result[] items: ", arrResult.size());
   
   // Loop through the array
   for (int i = 0; i < arrResult.size(); i++) {
      // Get the object representing each item in the array 
      JSONObject* arrItem = arrResult.getObject(i);
      // Display the value of result[n].display_name
      Print("display_name: ", arrItem.getString("display_name"));
      // Free the object representing the array entry
      delete arrItem;
   }
   
   // Clean up all the other objects instantiated
   delete arrResult;
   delete paging;
   delete root;
   delete parser;

While ydrol's JSON parser is very good in itself, this sort of code necessarily isn't pretty. It's what happens when you get a strongly typed (and compiled) language such as MQL4 colliding with a weakly typed (and interpreted) language such as Javascript.

 
JC:

This is really a complete change of topic from what the OP asked... Nevertheless, assuming that you are using ydrol's JSON parser from https://www.mql5.com/en/code/11134, then you need to walk the tree of objects as illustrated by the following example:

While ydrol's JSON parser is very good in itself, this sort of code necessarily isn't pretty. It's what happens when you get a strongly typed (and compiled) language such as MQL4 colliding with a weakly typed (and interpreted) language such as Javascript.

I don't think you can necessarily blame the code ugliness on the language differences because the JSON class could be rewritten in such a way to interact with JSON similar to an object vector. 

CJsonObjVector json(response); 

for(int i=0; i<json.Total(); i++)
   printf("\"display_name:\" @ index[%d] = %s", i, json[i].GetString("display_name")); 
 
nicholishen:

I don't think you can necessarily blame the code ugliness on the language differences because the JSON class could be rewritten in such a way to interact with JSON similar to an object vector. 

I wasn't thinking in terms of the array access in particular. It's more something like the following, which is somewhat harder to reproduce in a language such as MQL4:

var displayname = JSON.parse(resp).result[0].display_name;
 

I'm struggling to implement parse from JSON string that is sended from API and I get from webrequest MetaTrader. I not what to do more. 

https://www.mql5.com/en/code/11134

This is how receive this array with JSON STRING 

[{\"id\":1,\"provider\":\"-481414224\"},{\"id\":2,\"provider\":\"-481414224\"},{\"id\":3,\"provider\":\"-481414224\"}]"

I strip the bracket from API to get only one string JSON and treat in MQL but now I have to split the string and I have to insert quotes to close missing quote error. Even that

"{\"id\":1,\"provider\":\"-481414224\"}, / {\"id\":2,\"provider\":\"-481414224\"}, / {\"id\":3,\"provider\":\"-481414224\"}"


   res=WebRequest("GET",api_url,cookie,NULL,timeout,post,0,request_result,headers);
   //--- Checking errors
   if(res==-1)
   {
        Print("Error in WebRequest. Error code  =",GetLastError());
      MessageBox("Add the address '"+api_url+"' in the list of allowed URLs on tab 'Expert Advisors'","Error",MB_ICONINFORMATION);
    }
    else
    {
      //--- Load successfully
      Print("Server response: ", CharArrayToString(request_result));
      
      string s = CharArrayToString(request_result);
        // #STRING =  "[{\"id\":1,\"provider\":\"-481414224\"},{\"id\":2,\"provider\":\"-481414224\"},{\"id\":3,\"provider\":\"-481414224\"}]"

                        ushort u_sep='/';              
                        string string_split[];               
                        //--- Split the string to substrings
                        int k=StringSplit(s,u_sep,string_split);
                        for(int i=0;i<k;i++){
                                string_split[i] = StringConcatenate(string_split[i], """");
                                Print("i: ",i," = ",string_split[i]);
                        }    

                        JSONObject *jsons[100];

                        for(int i=0;i<ArraySize(string_split);i++)
                        {
                                string new_str = string_split[i];
                                Print("str: ", new_str);
                                JSONParser *parser = new JSONParser();

                                JSONValue *jv = parser.parse(new_str);
        //Print("PARSED:"+jv.toString());
        if (jv == NULL) {
                Print("error:"+(string)parser.getErrorCode()+parser.getErrorMessage());
                } 
        else 
                {

           if (jv.isObject()) { // check root value is an object. (it can be an array)

                JSONObject *jo = jv;             
                jsons[i] = jo;

              // Direct access - will throw null pointer if wrong getter used.
              Print("firstName:" + jo.getInt("id"));
              Print("provider:" + jo.getString("provider"));

              // Safe access in case JSON data is missing or different.
              if (jo.getString("id",new_str) ) Print("id = "+new_str);

              // Loop over object keys
              JSONIterator *it = new JSONIterator(jo);
              for( ; it.hasNext() ; it.next()) {
                Print("loop:"+it.key()+" = "+it.val().toString());
              }
              delete it;
            }
            delete jv;
          }
              delete parser;
        }
     }
JSON Parser
JSON Parser
  • www.mql5.com
SwingCyborg This Expert Advisor is based on your human ability to predict medium and long term trends. MACD vs Signal line It opens and close transactions depends on MACD vs signal line - upper - opens buy, closes sell, below - closes buy, opens sell. Universal EA This is my first Expert Advisor so please give feedback on how I can improve it...
 
Breno Perucchi:

Do not double post!

I have deleted your other topic.

Reason: