TCustomRESTRequest.AddFile转换文件名报错及文件上传失败求助
Delphi TCustomRESTRequest.AddFile 上传文件问题排查与解决
问题背景
API提供方给出的C#上传文件示例代码:
var client = new RestClient("hisurl"); client.Timeout = -1; var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "multipart/form-data"); request.AddHeader("v", "4.2"); request.AddHeader("j_token", "histoken"); request.AddFile("file", "/C:/Users/olivm/Documents/QA API Swagger/smartpacte2.pdf","application/.pdf"); IRestResponse response = client.Execute(request); Console.WriteLine(response.Content);
我用Delphi的TCustomRESTRequest编写了对应代码:
procedure AttachDocument(contract_id : Integer; pathFile : String); var RESTClient : TRESTClient; RESTRequest : TCustomRESTRequest; Response : TCustomRESTResponse; begin RESTClient := TRESTClient.Create(''); RESTRequest := TCustomRESTRequest.Create(nil); try RESTClient.BaseURL := 'myurl'; RESTRequest.Client := RESTClient; RESTRequest.Accept := 'application/json'; RESTRequest.Params.AddHeader('j_token','mytoken',[poDoNotEncode]); RESTRequest.Method := rmPOST; RESTRequest.AddFile('file',pathFile); RESTRequest.Execute; Response := RESTRequest.Response; ShowMessage(Response.Content); finally RESTRequest.Free; RESTClient.Free; end; end;
遇到的错误
运行时触发异常:
RUNTIME ERROR : Impossible converting variant of type (UnicodeString) to type (Int64)
误以为AddFile第一个参数是文件路径、第二个是Int64类型,尝试了两种写法:
RESTRequest.AddFile(pathFile,0);
RESTRequest.AddFile(pathFile,ctAPPLICATION_PDF);
但API始终返回错误:
{"errors":"no files found"}
解决方案
问题出在对Delphi TCustomRESTRequest.AddFile方法参数的误解上,正确的重载方法应该是:
procedure AddFile(const AName: string; const AFileName: string; const AContentType: string = ''; const AContentTransferEncoding: string = ''); overload;
也就是第一个参数是API期望的表单字段名(对应C#示例里的"file"),第二个是文件路径,第三个可选参数是文件MIME类型。
你之前的错误是因为调用了另一个重载(比如基于流或字节的版本),导致参数类型不匹配。修正后的代码如下:
procedure AttachDocument(contract_id : Integer; pathFile : String); var RESTClient : TRESTClient; RESTRequest : TCustomRESTRequest; Response : TCustomRESTResponse; begin RESTClient := TRESTClient.Create(''); RESTRequest := TCustomRESTRequest.Create(nil); try RESTClient.BaseURL := 'myurl'; RESTRequest.Client := RESTClient; RESTRequest.Accept := 'application/json'; // 补充API要求的v头部 RESTRequest.Params.AddHeader('v', '4.2', [poDoNotEncode]); RESTRequest.Params.AddHeader('j_token','mytoken',[poDoNotEncode]); RESTRequest.Method := rmPOST; // 正确调用AddFile:表单字段名、文件路径、MIME类型 RESTRequest.AddFile('file', pathFile, 'application/pdf'); RESTRequest.Execute; Response := RESTRequest.Response; ShowMessage(Response.Content); finally RESTRequest.Free; RESTClient.Free; end; end;
另外需要注意几个点:
- 补充C#示例里的
v:4.2头部,之前的Delphi代码漏掉了这个必要参数 - MIME类型要写正确的
application/pdf,不是application/.pdf - Delphi的REST组件会自动处理
multipart/form-data内容类型,不需要手动添加这个头部,避免冲突
内容的提问来源于stack exchange,提问作者Damky
相关产品推荐
相关产品推荐

