Home > Software design >  Incompatible types: 'System.TArray<System.Net.URLClient.TNameValuePair>' and 'T
Incompatible types: 'System.TArray<System.Net.URLClient.TNameValuePair>' and 'T

Time:01-02

I've been trying to use the NetHTTPRequest & NetHTTPClient components in Delphi to issue a basic authentication request, but I've been having trouble with the NetHTTPRequest.Get method...

Basically, the method needs three parameters, namely URL(String), memory stream, and the header of the type TNetHeader.

I don't know why, but when I try to pass my newly created header, I get the error mentionned in the title, namely

Incompatible types: 'System.TArray<System.Net.URLClient.TNameValuePair>' and 'TNameValuePair'

I don't know if I have to cast, and If I have to, cast it to what?

Of course, If I don't pass on the basic auth header, the server just returns a 401 because it doesn't see any credentials or header to decode...

Here is the code :

procedure TForm1.Button1Click(Sender: TObject);
var
  HTTPResponseString: String;

begin
  if IsLoggedIn = False then
  begin
    if Edit2.Text = '' then
    begin
      ShowMessage('Password cannot be empty');
      exit;
    end;

    BasicAuth := username   ':'   Edit2.Text; //   '£';
    AuthentificationPacket := EncodeBase64(UTF8Bytes(utf8string(BasicAuth)));

    HTTPHeader := TNetHeader.Create('Authorization: Basic', AuthentificationPacket);

    try
      HTTPResponseLogin := NetHTTPRequest1.Get(HTTPLoginRequest, nil, HTTPHeader);

      ShowMessage(HTTPResponselogin.ContentAsString());
      IsLoggedIn := True;

    except
      on E: Exception do
        ShowMessage(E.Message);

    end;

    Button1.Text := 'LOG OFF';
  end
  else if IsLoggedIn then
  begin
    Edit1.Text := '';
    Edit2.Text := '';
    username := '';
    password := '';
    tagid := '';

    Button1.Enabled := False;
    Button1.Text := 'LOG IN';
    IsLoggedIn := False;

    Timer1.Enabled := False;
    IdleTimer := 0;

    Application.OnIdle := nil;
  end;

end;

The problematic line is of course, the NetHTTPRequest1.Get(HTTPLoginRequest, nil, HTTPHeader);

Where HTTPHeader is marked as incompatible...

Any help is appreciated!

CodePudding user response:

Look at the declaration of TNetHTTPRequest.Get() more carefully:

function Get(const AURL: string; const AResponseContent: TStream = nil; const AHeaders: TNetHeaders = nil): IHTTPResponse;

The 3rd parameter takes a TNetHeaders(plural), but you are passing it a TNetHeader (singular) instead. It wants an array of name/value pairs.

Also, Basic is not part of an Authorization header's name, it is part of its value instead.

Try something more like this:

procedure TForm1.Button1Click(Sender: TObject);
var
  BasicAuth, AuthentificationPacket: string;
  HTTPHeader: TNetHeader;
begin
  if not IsLoggedIn then
  begin
    if Edit2.Text = '' then
    begin
      ShowMessage('Password cannot be empty');
      Exit;
    end;

    BasicAuth := username   ':'   Edit2.Text; //   '£';
    AuthentificationPacket := 'Basic '   EncodeBase64(UTF8Bytes(UTF8String(BasicAuth)));

    HTTPHeader := TNetHeader.Create('Authorization', AuthentificationPacket);

    try
      ShowMessage(NetHTTPRequest1.Get(HTTPLoginRequest, nil, [HTTPHeader]).ContentAsString());
    except
      on E: Exception do begin
        ShowMessage(E.Message);
        Exit;
      end;
    end;

    IsLoggedIn := True;
    Button1.Text := 'LOG OFF';
  end
  else
  begin
    Edit1.Text := '';
    Edit2.Text := '';
    username := '';
    password := '';
    tagid := '';

    Button1.Enabled := False;
    Button1.Text := 'LOG IN';
    IsLoggedIn := False;

    Timer1.Enabled := False;
    IdleTimer := 0;

    Application.OnIdle := nil;
  end;
end;

Alternatively, you can use the TNetHTTPRequest.CustomHeaders property instead of the AHeaders parameter:

procedure TForm1.Button1Click(Sender: TObject);
var
  BasicAuth: string;
begin
  if not IsLoggedIn then
  begin
    if Edit2.Text = '' then
    begin
      ShowMessage('Password cannot be empty');
      Exit;
    end;

    BasicAuth := username   ':'   Edit2.Text; //   '£';
    NetHTTPRequest1.CustomHeaders['Authorization'] := 'Basic '   EncodeBase64(UTF8Bytes(UTF8String(BasicAuth));

    try
      ShowMessage(NetHTTPRequest1.Get(HTTPLoginRequest).ContentAsString());
    except
      on E: Exception do begin
        ShowMessage(E.Message);
        Exit;
      end;
    end;

    IsLoggedIn := True;
    Button1.Text := 'LOG OFF';
  end
  else
  begin
    Edit1.Text := '';
    Edit2.Text := '';
    username := '';
    password := '';
    tagid := '';

    Button1.Enabled := False;
    Button1.Text := 'LOG IN';
    IsLoggedIn := False;

    Timer1.Enabled := False;
    IdleTimer := 0;

    Application.OnIdle := nil;
  end;
end;
  • Related