简体   繁体   中英

using curl via Indy in Delphi XE2

I am trying to use IdHTTP to equivalence this curl operation (known to work) in Delphi XE2:

 curl http://hub.Healthdata.gov/api/action/datastore_search --data-urlencode '
 {
  "resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54",
  "filters": {
    "provider_id": 393303
   }
   }'

I have tried the following code, but it does not work ... can someone advise as to correct procedure? It replies bad request. Thank you.

procedure TfrmMain.get1Click(Sender: TObject);
var
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  result:string;

begin
  lParamList := TStringList.Create;
  lParamList.Add('"resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54"');
  lParamList.Add('"filters": {"provider_id": 393303}');

  lHTTP := TIdHTTP.Create(nil);
  try
    Result := lHTTP.Post('http://hub.Healthdata.gov/api/action/datastore_search --data-urlencode ',
     lParamList);
  finally
    FreeAndNil(lHTTP);
    FreeAndNil(lParamList);
  end;
end;

The --data-urlencode parameter is not part of the URL, it merely tells curl how to encode the data being posted, so you do not pass that portion to TIdHTTP at all.

The part of the curl command between single quotes is the actual data to post. --data-urlencode tells curl to send the data using the HTTP POST method, using the application/x-www-form-urlencoded content type, and url-encoding the data.

The TStrings version of TIdHTTP.Post() does all of that. Normally, application/x-www-form-urlencoded is used with "name=value" string pairs, however there is no name being specified in the curl command, only a value. If curl supplies a default name, then the Delphi code would look like this:

procedure TfrmMain.get1Click(Sender: TObject);
var
  json: string;
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  result:string;
begin
  json := CRLF +
          '{' + CRLF +
          ' "resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54",' + CRLF +
          ' "filters": {' + CRLF +
          '   "provider_id": 393303' + CRLF +
          ' }' + CRLF +
          '}';
  lParamList := TStringList.Create;
  try
    lParamList.Add('somename='+json);
    lHTTP := TIdHTTP.Create(nil);
    try
      Result := lHTTP.Post('http://hub.Healthdata.gov/api/action/datastore_search', lParamList);
    finally
      lHTTP.Free;
    end;
  finally
    lParamList.Free;
  end;
end;

Otherwise, if curl sends the specified data as-is by itself, then the Delphi code would look like this instead:

procedure TfrmMain.get1Click(Sender: TObject);
var
  json: string;
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  result:string;
begin
  json := CRLF +
          '{' + CRLF +
          ' "resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54",' + CRLF +
          ' "filters": {' + CRLF +
          '   "provider_id": 393303' + CRLF +
          ' }' + CRLF +
          '}';
  lParamList := TStringList.Create;
  try
    lParamList.Add(json);
    lHTTP := TIdHTTP.Create(nil);
    try
      Result := lHTTP.Post('http://hub.Healthdata.gov/api/action/datastore_search', lParamList);
    finally
      lHTTP.Free;
    end;
  finally
    lParamList.Free;
  end;
end;

The only difference being what parameter value gets passed to TStringList.Add() .

They are not URL parameters it's part of the POST body that's just URL encoded.

You need to encode the JSON string and write it to a stream, perhaps TMemoryStream and then call:

TIdHTTP.Post(url,stream);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM