views:

4761

answers:

5

There's a web services I want to call in my application, I can use it with importing the WSDL or by just use "HTTP GET" with the URL and parameters, so I prefer the later because it's simple thing.

I know I can use indy idhttp.get, to do the job, but this is very simple thing and I don't want to add complex indy code to my application.

UPDATE: sorry if I was not clear, I meant by "not to add complex indy code", that I don't want add indy components for just this simple task, and prefer more lighter way for that.

+4  A: 

Calling a RESTful web service using Indy is pretty straight forward.

Add IdHTTP to your uses clause. Remember that IdHTTP needs the "HTTP://" prefix on your URLs.

function GetURLAsString(aURL: string): string;
var
  lHTTP: TIdHTTP;
  lStream: TStringStream;
begin
  lHTTP := TIdHTTP.Create(nil);
  lStream := TStringStream.Create(Result);
  try
    lHTTP.Get(aURL, lStream);
    lStream.Position := 0;
    Result := lStream.ReadString(lStream.Size);
  finally
    FreeAndNil(lHTTP);
    FreeAndNil(lStream);
  end;

end;

Bruce McGee
The question was if it could be done without Indy
Lars Truijens
The question was to not add complex Indy code. The code isn't complex.
Bruce McGee
Bruce, Lars is right, I said in my questions I don't want to use indyt "idhttp.get", it's the simplest way but I wanted the lighted way :)
Mohammed Nasman
Your "lightest" option is to use external code, whether it's Indy, Synapse or WinINet. If you can't or won't use Delphi components or classes, use Delphi's wrapper functions around WinINet. Also external, but at least the DLL is installed with Windows.
Bruce McGee
+6  A: 

You could use the WinINet API like this:

uses WinInet;

function GetUrlContent(const Url: string): string;
var
  NetHandle: HINTERNET;
  UrlHandle: HINTERNET;
  Buffer: array[0..1024] of Char;
  BytesRead: dWord;
begin
  Result := '';
  NetHandle := InternetOpen('Delphi 5.x', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);

  if Assigned(NetHandle) then 
  begin
    UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);

    if Assigned(UrlHandle) then
      { UrlHandle valid? Proceed with download }
    begin
      FillChar(Buffer, SizeOf(Buffer), 0);
      repeat
        Result := Result + Buffer;
        FillChar(Buffer, SizeOf(Buffer), 0);
        InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
      until BytesRead = 0;
      InternetCloseHandle(UrlHandle);
    end
    else
      { UrlHandle is not valid. Raise an exception. }
      raise Exception.CreateFmt('Cannot open URL %s', [Url]);

    InternetCloseHandle(NetHandle);
  end
  else
    { NetHandle is not valid. Raise an exception }
    raise Exception.Create('Unable to initialize Wininet');
end;

source: http://www.scalabium.com/faq/dct0080.htm

The WinINet API uses the same stuff InternetExplorer is using so you also get any connection and proxy settings set by InternetExplorer for free.

Lars Truijens
Getting the IE settings "for free" is only a feature if you use IE. :)
Bruce McGee
Thanks Lars, that's the lighted way :)
Mohammed Nasman
A: 

Thanks Lars, but I don't to download any file, just pass URL with parameters and get the result.

Bruce, I want to do that without Indy or other components :)

Mohammed Nasman
Please use the comments for these kind of...well...comments :)The function is called DownloadFile, but all it does is get the result from the webserver. So it also 'downloads' 'files' like a wsdl.
Lars Truijens
And there are lots of other functions in the WinINet API you could use if my example isn't exactly what you need.
Lars Truijens
I'm not sure your goal is realistic. Using a third party component or class that deals with all of the issues of HTTP for you is basic code reuse and just makes sense. Doing the same thing yourself will complicate your code, not simplify it.
Bruce McGee
WinINet API does the same. You could consider this a third party component, but at least it is always installed on Windows. :)
Lars Truijens
I agree with Bruce. Much work redoing what is already done.
Fabricio Araujo
A: 

Use the Synapse TCP/IP function in the HTTPSEND unit (HTTPGetText, HTTPGetBinary). It will do the HTTP pull for you and doesn't require any external DLL's other than Winsock. The latest SVN release works perfectly well in Delphi 2009. This uses blocking function calls, so no events to program.

skamradt
HTTP calls in Indy are also blocking.
Bruce McGee
+1  A: 

If it's okay to download to a file, you can use TDownloadURL from the ExtActns unit. Much simpler than using WinInet directly.

procedure TMainForm.DownloadFile(URL: string; Dest: string);
var
  dl: TDownloadURL;
begin
  dl := TDownloadURL.Create(self);
  try
    dl.URL := URL;
    dl.FileName := Dest;
    dl.ExecuteTarget(nil); //this downloads the file
    dl.Free;
  except
    dl.Free;
  end;
end;

It's also possible to get progress notifications when using this. Simply assign an event handler to TDownloadURL's OnDownloadProgress event.

Michael Madsen