繁体   English   中英

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

[英]How to convert C# code calling a rest service to Delphi XE4

谁能帮助我将以下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

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;

感谢雷米的提示,这对我非常有帮助,所以我创建了具有两个功能的本机,现在看来一切正常! 我使用Delphi 2006和Delphi XE2。 dpallas您可以根据需要免费修改此代码:

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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