[英]How do I get a dynamic TClientDataset (based on TRESTResponseDataSetAdapter) to correctly recognise boolean values?
我已經在Delphi XE5中構建了一個利用Rest庫的delphi客戶端示例:
所有這些都由ASP.net Web API提供服務,該API根據來自Delphi的動態查詢生成數據集。 我可以成功運行查詢並將數據返回給客戶端並呈現數據,但是布爾字段被呈現為空白。
編輯令人驚訝的是,Embarcadero的TRestResponseDatasetAdapter在內部執行此操作以創建字段:
procedure TCustomJSONDataSetAdapter.CB_CollectFieldDefs(const AJSONObject: TJSONObject);
var
LJSONPair: TJSONPair;
begin
for LJSONPair in AJSONObject do
begin
DoAddDataSetFieldDef(LJSONPair.JsonString.Value, ftString);
end;
end;
字段類型都被硬編碼為ftString!
這是返回的json:
"Table": [
{
"Id": 34,
"Node": "Navision_ASN_1",
"FormatId": 2,
"Value": null,
"ParentID": null,
"DocumentOrder": 1,
"Combined": false,
"Delimiter": "",
"ValueType": 0,
"Ignore": false,
"IsIndexer": false,
"IsCounter": false,
"StringFormat": null
},
{
"Id": 35,
"Node": "MessageHeader",
"FormatId": 2,
"Value": null,
"ParentID": 34,
"DocumentOrder": 2,
"Combined": false,
"Delimiter": "",
"ValueType": 0,
"Ignore": false,
"IsIndexer": false,
"IsCounter": false,
"StringFormat": null
},
{
"Id": 52,
"Node": "Consignment",
"FormatId": 2,
"Value": null,
"ParentID": 34,
"DocumentOrder": 13,
"Combined": false,
"Delimiter": "",
"ValueType": 0,
"Ignore": false,
"IsIndexer": false,
"IsCounter": false,
"StringFormat": null
},
{
"Id": 53,
"Node": "Line",
"FormatId": 2,
"Value": null,
"ParentID": 52,
"DocumentOrder": 18,
"Combined": false,
"Delimiter": "",
"ValueType": 0,
"Ignore": false,
"IsIndexer": false,
"IsCounter": false,
"StringFormat": null
}
]
你不能!
問題歸結於Embarcadero Delphi的TJsonObject類。 在Rest.Response.Adapter單元中,將返回的json解析為TJsonObject,然后在CB_CollectFieldDefs和CB_CollectFieldData中迭代對象中的所有TJsonPair。
第一個問題:CB_CollectionFieldDefs將ftString硬編碼為要添加到每個字段定義的dataSet的數據類型。 因此,我從Web API調用中返回了字段類型,以消除猜測並手動構建了字段定義。 當RestResponseDataSetAdapter具有字段定義時,該單元將正確跳過CB_CollectionFieldDefs,這將導致第二個問題。
第二個問題 :對象中的TjsonPair無法正確解析布爾json值。 到調用CB_CollectFieldData時,所有應該為變量類型的布爾值都是空字符串。 因此,我們得到了異常“無法將類型(UnicodeString)的變體轉換為類型(Boolean)”。
可悲的是,我不得不放棄這套有希望的組件,以增強Fabricio Colombo出色的rest client api。 使用他的GetAsDataSet邏輯中的模式,我創建了許多發布方法來發布json(因為從內置的delphi單元創建的json是不正確的,所以我用SuperObject代替了該方法)。 我介紹了PostJson和CreateDataset ,它們都返回TClientDataSets。
function TResource.CreateDataset(data: string; table: string = ''; titles: string = ''): TClientDataSet;
var
vJson: ISuperObject;
begin
vJson := SuperObject.SO(data);
Result := TJsonToDataSetConverter.CreateDataSetMetadata(vJson, table, titles);
TJsonToDataSetConverter.ToDataSet(Result, vJson.O[table]);
end;
// which allows me to do:
ds := jsonrestclient1.Resource(url)
.ContentType(RestUtils.MediaType_Json)
.Accept(restutils.MediaType_Json)
.PostJson(json, 'Table', 'Titles');
// or
rs := jsonrestclient1.Resource(url)
.ContentType(RestUtils.MediaType_Json)
.Accept(restutils.MediaType_Json);
data:= rs.PostJson(Query) ;
vJson := SO(data);
fHasMore := vJson.B['HasMore'];
ds:= rs.CreateDataset(data, 'Table', 'Titles');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.