Our testing of the new BETA (RO_VERSION = ‘9.5.0.1367’) shown that the TRORttiClientCache.GetProperties_OriginalSort method still incorrectly works (our initial topic is here).
to face the bug it’s need to have simultaneously two kinds of clients. The first SOAP client uses “strictOrder=true” and the second one is REST and uses “strictOrder=false” (in our case C# and Angular).
This workflow leads to the problem:
Run client (1) -> a strict set of properties is put in fProperties_strict
Run client (2) -> the SAME strict set from fProperties_strict is sorted and its reference is added to fProperties.
Run client (1) again -> fProperties_strict contains the SORTED set of properties = BUG.
can you test this code in your environment, pls?
it should fix this issue.
TRORttiClientCache.GetProperties_OriginalSort
function TRORttiClientCache.GetProperties_OriginalSort(const aType: TRttiType;
const aStrictOrder: Boolean): TArray<TRttiProperty>;
var
flat: TArray<TArray<TRttiProperty>>;
t: TRttiType;
depth: Integer;
dc: TDelegatedComparer<TRttiProperty>;
ah: TList<TRttiProperty>;
p: TRttiProperty;
lResult: TArray<TRttiProperty>;
begin
Result := nil;
BeginRead;
try
if aStrictOrder then begin
if fProperties_strict.TryGetValue(aType, result) then exit;
end
else begin
if fProperties.TryGetValue(aType, result) then exit;
end;
if not fProperties_strict.TryGetValue(aType, result) then begin
BeginWrite;
try
if not fProperties_strict.TryGetValue(aType, result) then begin
t := aType;
depth := 0;
while t <> nil do
begin
Inc(depth);
t := t.BaseType;
end;
SetLength(flat, depth);
t := aType;
while t <> nil do
begin
flat[depth-1] := t.GetDeclaredProperties;
Dec(depth);
t := t.BaseType;
end;
Result := TArrayHelper.Concat<TRttiProperty>(flat);
ah := TList<TRttiProperty>.Create;
try
for p in result do
if CanProcessProperty(p) then ah.Add(p);
Result := ah.ToArray;
finally
ah.Free;
end;
fProperties_strict.Add(aType,result);
end;
finally
EndWrite;
end;
end;
if not aStrictOrder then begin
BeginWrite;
try
if not fProperties.TryGetValue(aType, lResult) then begin
dc := TDelegatedComparer<TRttiProperty>.Create(
function (const Left, Right: TRttiProperty): Integer
begin
Result := CompareText(Left.Name, Right.Name);
end);
try
SetLength(lResult, Length(result));
if Length(result) > 0 then
TArray.Copy<TRttiProperty>(result, lResult, Length(result));
result := lResult;
TArray.Sort<TRttiProperty>(result, dc);
finally
dc.Free;
end;
fProperties.Add(aType,result);
end
else
result := lResult;
finally
EndWrite;
end;
end;
finally
EndRead;
end;
end;