问题描述
我正在Windows 10 64bit上使用Delphi 10.4(带有补丁1、2和3)来构建VCL Web客户端应用程序。
我有一个在RAD Server上运行的API,使用下面的VCL Webclient应用程序可以毫无问题地从中获取信息。但是,当我尝试通过POST
方法将数据插入API资源时,从TRESRequest.Execute()
方法调用中收到以下错误消息:
目标多字节代码页中不存在Unicode字符的映射
尽管我收到此错误消息,但JSON数据正在发送到API,并正确保存到数据库中。似乎在Execute()
方法的某个点上,将数据发送到服务器后会生成错误。
我已经尝试过TEncoding.UTF8.GetBytes()
,TEncoding.ASCII.GetBytes()
和Unicode
,但没有成功。
这是我的代码:
procedure TForm1.BTPostClick(Sender: TObject);
var
strjson : string;
jo : TJSONObject;
begin
strjson :=
'{' +
'"CUST_ID": 1500,' +
'"CUST_NAME": "John Doe Max",' +
'"CUST_COUNTERTOTAL": "500",' +
'"CUST_DETAILS": "This is just a test"' +
'}';
// jo := TJSONObject.ParseJSONValue(TEncoding.Unicode.GetBytes(Strjson),0) as TJSONObject;
// jo := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Strjson),0) as TJSONObject;
jo := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(Strjson),0) as TJSONObject;
Memo1.Clear;
Memo1.Lines.Add(jo.ToString);
RestRequest1.ClearBody;
RestRequest1.Method := rmPost;
RestResponse1.ResetToDefaults;
RestRequest1.AddBody(jo);
RestRequest1.Execute; // ==> error: No mapping for the Unicode character exists in the target multi-byte code page
end;
服务器端代码:
procedure TMytestResource1.MytestPost(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
s : string;
i : integer;
jo : TJSONObject;
begin
jo := TJSONObject.Create;
jo.AddPair('Response Line 1','Apple is maçã');
jo.AddPair('Response Line 2','Foot is pé ');
jo.AddPair('Response Line 3','There is lá');
jo.AddPair('Exceção Line 3',TJsonString.Create('Exception is exceção'));
//s := jo.ToString; at this point the characters has accents
AResponse.Body.SetValue(jo,True);
end;
REST组件的配置如下:
RestClient1.Accept := 'application/json,text/plain; q=0.9,text/html;q=0.8,';
RestClient1.AcceptCharset := 'utf-8;q=0.8';
RestClient1.AcceptEnconding := 'utf-8';
RestClient1.FallbackCharsetEncoding := 'utf-8';
RestClient1.ContentType := 'application/json'
RestRequest1.Accept := 'application/json,'
RestRequest1.AcceptCharset := 'utf-8;q=0.8';
RestResponse1.ContentEncoding := '';
RestResponse1.ContentType := '';
新服务器端代码(工作正常):
procedure TMytestResource1.CadastraUser(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
s : string;
i : integer;
jo : TJSONObject;
Strm : TStringStream;
begin
jo := TJSONObject.Create;
jo.AddPair('Response Line 1','Apple is maçã');
jo.AddPair('Response Line 2','Foot is pé');
jo.AddPair('Response Line 3','There is lá');
jo.AddPair('Response Line 4','Useful is útil');
//AResponse.Headers.SetValue('Content-Type','application/json; charset=utf-8'); ==> This line does not make any effect on response
try
// Strm := TStringStream(jo.ToJSON,TEncoding.UTF8); ==> does not work.
Strm := TStringStream.Create(jo.ToJSON,TEncoding.UTF8);
// AResponse.Body.SetStream(Strm,'application/json; charset=utf-8',true); ==> This line causes an error on VCL WebClient during RestRequest.Execute() method,error is "Invalid enconding name."
AResponse.Body.SetStream(Strm,'application/json',true); // this works fine.
finally
jo.Free;
end;
end;
所以现在出现了新问题:
-
为什么相同的程序在Windows 7下的Delphi 10.3.1 Tokyo中也能正常工作,但是现在在Windows 10的Delphi 10.4 Sydney(补丁1,2,3)中,它却需要UTF-8编码?是Delphi 10.4问题吗?是Windows 10问题吗?
-
在我原来的服务器端代码中,我有许多端点使用命令
AResponse.Body.SetValue(myJSONObject,True);
发送响应,我是否应该用两个新命令替换所有端点?Strm := TStringStream.Create(jo.ToJSON,TEncoding.UTF8); AResponse.Body.SetStream(Strm,true);
Procedure TCustomrestRequest.Execute
...
if LMimeKind <> TMimeTypes.TKind.Binary then
begin
LEncoding := TEncoding.GetEncoding(FClient.FallbackCharsetEncoding); //==> This line is returning nil,though FClient.FallbackCharsetEncoding is filled with 'utf-8'
LContentIsstring := True;
end;
end
else
begin
// Even if no fallback,handle some obvIoUs string types
if LMimeKind = TMimeTypes.TKind.Text then
LContentIsstring := True;
end;
end;
if LContentIsstring then
LContent := FClient.HTTPClient.Response.ContentAsstring(LEncoding); // ==> this line is generating the error
finally
LEncoding.Free;
end;
...
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)