如何将调用rest服务的c#代码转换为Delphi XE4

本文关键字:转换 代码 Delphi XE4 调用 rest 服务 | 更新日期: 2023-09-27 17:49:32

谁能帮助我如何将以下c#代码转换为Delphi XE4?

//Libraries
//Custom parameters
string url = "REST_SERVICE_URL";
string sAuthorization = "USERNAME:PASSWORD";
string fileName = "FILENAME.zip";
string filePath = @"FILE_PATH" + fileName;
//Identificate separator
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 
//Encoding
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("'r'n--" + boundary + "'r'n");
//Creation and specification of the request
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;  //Authentication
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(sAuthorization);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
wr.Headers.Add("Authorization: Basic " + returnValue);
//Writting of the file
Stream rs = wr.GetRequestStream();
rs.Write(boundarybytes, 0, boundarybytes.Length);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(filePath);
rs.Write(formitembytes, 0, formitembytes.Length);
rs.Write(boundarybytes, 0, boundarybytes.Length); 
string headerTemplate = "Content-Disposition: form-data; name='"{0}'";filename='"{1}'"'r'nContent-Type: {2}'r'n'r'n"; 
string header = string.Format(headerTemplate, "file", fileName, "application/octet-stream");
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length); 
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) = 0)
{
    rs.Write(buffer, 0, bytesRead);
}
fileStream.Close(); 
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("'r'n--" + boundary + "--'r'n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
rs = null; 
try
{
    //Get the response

如何将调用rest服务的c#代码转换为Delphi XE4

Delphi与Indy一起发货,Indy具有TIdHTTP组件和TIdMultipartFormDataStream级,例如:

uses
  ..., IdHTTP, IdMultipartFormData;
var
  filename: string;
  filePath: string;
  HTTP: TIdHTTP;
  PostData: TIdMultipartFormDataStream;
begin
  fileName := 'FILENAME.zip';
  filePath := 'FILE_PATH' + fileName;
  PostData := TIdMultipartFormDataStream.Create;
  try
    PostData.AddFile('file', filePath, 'application/octet-stream');
    HTTP := TIdHTTP.Create;
    try
      HTTP.Request.Username := 'USERNAME';
      HTTP.Request.Password := 'PASSWORD';
      HTTP.Request.BasicAuthentication := True;
      HTTP.Post('REST_SERVICE_URL', PostData);
    finally
      HTTP.Free;
    end;
  finally
    PostData.Free;
  end;
  //process the response as needed
end;

TIdHTTP.Post()可以返回服务器的响应数据作为String:

var
  Response: String;
Response := HTTP.Post('REST_SERVICE_URL', PostData);

TStream:

var
  Response: TMemoryStream;
Response := TMemoryStream.Create; // or whatever TStream class you want
try
  HTTP.Post('REST_SERVICE_URL', PostData, Response);
  ...
finally
  Response.Free;
end;

感谢Remy的提示,这对我很有帮助,所以我创建了这个有两个功能的单位,现在一切似乎都很好!我使用Delphi 2006和Delphi XE2。当然,你可以根据自己的需要自由修改这段代码:

unit Umyf;
interface
{
 //Myf REST Calls for https://www1.gsis.gr
 //George Panagiotopoulos
 //gppanagiotopoulos@yahoo.gr
 //Created 07/04/2014
********************************************************************************
 //PostMyfFile : Posting file to server
 //how to use PostMyfFile:
 // var id : integer;status,errormsg : string; succeed: Boolean;
 //filePath is the full path of the file : filepath + filename
 //succeed := PostMyfFile(URL,filePath, Username,Password,id,status,errormsg);
 //GetMyfFile  : getting file status from server
 //how to use GetMyfFile:
 //var id : integer;status,errormsg : string; succeed: Boolean;
 //id:=26099; // file id
 //succeed := GetMyfFile(URL,Username,Password,id,status,errormsg);
********************************************************************************
 //To use Indy's OpenSSL class, TIdSSLIOHandlerSocketOpenSSL,
 //you may need ssleay32.dll, libeay32.dll and ssleay32.dll (x32 or x64).
 //You can get them from http://indy.fulgan.com/ZIP/
 //DELPHI2010ANDUP directive is for delphi 2009 to XE5
}
{$IFDEF VER200}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
{$IFDEF VER210}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
{$IFDEF VER220}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
{$IFDEF VER230}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
{$IFDEF VER240}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
{$IFDEF VER250}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
{$IFDEF VER260}
  {$DEFINE DELPHI2010ANDUP}
{$ENDIF}
uses Classes,SysUtils,Windows,IdHTTP,IdSSLOpenSSL,IdGlobal,IdMultipartFormData;
function PostMyfFile(const URL, FilePath, Username, Password  : string;
                     var id : integer;
                     var status : string;
                     var errormsg : string):Boolean;
function GetMyfFile (const URL, Username, Password  : string; const id : integer;
                     var status : string;
                     var errormsg : string):Boolean;

implementation
//default messages from API
const s_FAIL  = 'fail';
      s_OK    = 'ok';
      s_PR    = 'processing';
      s_Bound = '---------------------------';
      CR      = #13;
procedure ParseXmlStr(XmlStr : string;
                      var id : integer;
                      var status : string;
                      var errormsg : string);
var StrList : TStringList;
    i       : integer;
begin
   id:=0;
   status:=s_FAIL;
   if xmlStr<>Emptystr then
   begin
     StrList := TStringList.Create;
     try
       StrList.Text      := AnsiLowerCase(XmlStr);   //make all letters lowercase
       StrList.Delimiter := CR;
       for I := 0 to StrList.Count-1 do
       begin
          if Pos('<id>',StrList[i])>0      then
              id:= StrToIntDef(
                               Trim(
                                    StringReplace(
                                                  StringReplace(StrList[i], '<id>', '',[rfReplaceAll]),
                                                  '</id>', '',[rfReplaceAll])
                                    )
                               ,0);
          if Pos('<status>',StrList[i])>0  then
             status := Trim(
                            StringReplace(
                                          StringReplace(StrList[i], '<status>', '',[rfReplaceAll]),
                                          '</status>', '',[rfReplaceAll])
                            );
          if Pos('<error>',StrList[i])>0  then
          begin
             errormsg:=StringReplace(
                                    StringReplace(StrList[i], '<error>', '',[rfReplaceAll]),
                                    '</error>', '',[rfReplaceAll]);
          end;
       end;
     finally
        StrList.Free;
     end;
   end;
end;
function PostMyfFile(const URL,FilePath,Username,Password  : string;
                     var Id : integer;
                     var Status : string;
                     var Errormsg : string):Boolean;
var
  HTTP: TIdHTTP;
  PostData: TIdMultipartFormDataStream;
  Response,Bound : string;
begin
  Result:= false;
  Id     := 0;
  Status := s_FAIL;
  try
    //check if file exists
    if not FileExists(FilePath) then raise Exception.Create(format('File <%s> does not exist!!',[FilePath]));
    //calculate Boundary
    Bound := s_Bound+IntToHex(GetTickcount,15);
    PostData := TIdMultipartFormDataStream.Create;
    try
      // add file to  DataStream
      PostData.AddFile('file', filePath, 'application/octet-stream');
      HTTP := TIdHTTP.Create;
      try
        //add ssl support if needed
        if Pos('https://', AnsiLowerCase(url))>0 then
        begin
           HTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
{$IFNDEF DELPHI2010ANDUP}
          //Delphi 2006 requires this else create exception
          ( HTTP.IOHandler as TidSSLioHandlerSocketOpenSSL).SSLOptions.Method := sslvSSLv23 ;
          ( HTTP.IOHandler as TidSSLioHandlerSocketOpenSSL).SSLOptions.Mode:=sslmClient;
{$ENDIF}
      end;
{$IFNDEF DELPHI2010ANDUP}
        //Delphi 2006 requires this to avoid timeout
        HTTP.ReadTimeout := 0;
{$ENDIF}
        HTTP.Request.ContentType := 'multipart/form-data; boundary='+ Bound;
        HTTP.Request.Username := Username;
        HTTP.Request.Password := Password;
        HTTP.Request.Connection := 'Keep-Alive';
        HTTP.Request.BasicAuthentication := True;
        //POST  DataStream
        response := HTTP.Post(URL, PostData);
        //handle response
        ParseXmlStr(Response,Id,Status,Errormsg);
        Result := (Id>0) and ((status =s_OK)or(Status =s_PR));
      finally
        HTTP.Free;
      end;
    finally
      PostData.Free;
    end;
  except
     on e : exception do
        Errormsg := e.Message;
  end;
end;
function GetMyfFile(const URL,Username,Password  : string;
                    const ID : integer;  //ID of the file : stored in database
                    var Status : string;
                    var Errormsg : string):Boolean;
var
  HTTP: TIdHTTP;
  Sid : integer;
  Response : string;
begin
  Result:= false;
  Sid:= 0;
  Status:= s_FAIL;
  try
    HTTP := TIdHTTP.Create;
    try
      //add ssl support if needed
      if Pos('https://', AnsiLowerCase(url))>0 then
      begin
         HTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
{$IFNDEF DELPHI2010ANDUP}
        //Delphi 2006 requires this else create exception
        ( HTTP.IOHandler as TidSSLioHandlerSocketOpenSSL).SSLOptions.Method := sslvSSLv23 ;
        ( HTTP.IOHandler as TidSSLioHandlerSocketOpenSSL).SSLOptions.Mode:=sslmClient;
{$ENDIF}
      end;
{$IFNDEF DELPHI2010ANDUP}
      //Delphi 2006 requires this to avoid timeout
      HTTP.ReadTimeout := 0;
{$ENDIF}
      HTTP.Request.Username:= Username;
      HTTP.Request.Password:= Password;
      HTTP.Request.Connection := 'Keep-Alive';
      HTTP.Request.BasicAuthentication := True;
      //Get url + id of the file
      if (url[Length(url)]<> '/') then
         response:= HTTP.GET(url + '/' + inttostr(id))
      else
         response:= HTTP.GET(url + inttostr(id));
      //handle response
      ParseXmlStr(response,Sid,Status,Errormsg);
      Result := (Id=Sid) and ((Status =s_OK)or(Status =s_PR));
    finally
      if assigned(HTTP.IOHandler) then HTTP.IOHandler.Free;
      HTTP.Free;
    end;
  except
     on e : exception do
        Errormsg := e.Message;
  end;
end;
end.