Search code examples
jsondelphidelphi-11-alexandria

Delphi 11.3 - Unable to create/Add JSONs from variant


I am migrating some projects from Delphi 10.4 to Delphi 11.3. I am facing some problems with the JSON library:

See the following codes:

First case:

function TestCreate;
var
  LValue: Variant;
  LJSON: TJSONNumber;
begin
  LValue := 100;
  LJSON := TJSONNumber.Create(LValue);
end;

Compiling this, it results in:

  [dcc64 Error] _Unit.pas(74): E2251 Ambiguous overloaded call to 'Create'
  System.JSON.pas(435): Related method: constructor TJSONNumber.Create(const string);
  System.JSON.pas(439): Related method: constructor TJSONNumber.Create(const Double);

Second case:

function TestAddPair;
var
  LValue: Variant;
  LJSON: TJSONObject;
begin
  LValue := 100;
  LJSON := TJSONObject.Create();
  LJSON.AddPair('Test', LValue);
end;

Compiling this, it results in:

  [dcc64 Error] _Unit.pas(77): E2251 Ambiguous overloaded call to 'AddPair'
  System.JSON.pas(661): Related method: function TJSONObject.AddPair(const string; const Boolean): TJSONObject;
  System.JSON.pas(651): Related method: function TJSONObject.AddPair(const string; const Double): TJSONObject;
  System.JSON.pas(636): Related method: function TJSONObject.AddPair(const string; const string): TJSONObject;

Both used to work properly on Delphi 10.4, but on Delphi 11.3 they do not compile. Is there a way to let them compile? I'd prefer not to modify each command that uses a Variant to create/add a JSON.


Solution

  • This is my function to convert from Variant to JSON.

    It identifies if the Variant contains a Null, Number, String, Bool or Date, returning the corresponding JSONValue, it also checks if the Variant is an array so it returns its values in a TJSONArray.

    function VariantToJSON(Value: Variant): TJSONValue;
      var i: integer;
          JSONArray: TJSONArray;
      function VarToInt(Value: Variant): integer;
      begin
        Result := Value;
      end;
      function VarToFloat(Value: Variant): double;
      begin
        Result := Value;
      end;
      function Item(Value: Variant): TJSONValue;
      begin
        case VarType(Value) of
          varEmpty, varNull, varUnknown:
            Result := TJSONNull.Create;
          varSmallint, varInteger, varShortInt, VarInt64:
            Result := TJSONNumber.Create(VarToInt(Value));
          varSingle, varDouble, varCurrency:
            Result := TJSONNumber.Create(VarToFloat(Value));
          varDate:
            Result := TJSONString.Create(DateToISO8601(Value));
          varBoolean:
            Result := TJSONBool.Create(Value);
          else
            Result := TJSONString.Create(Value);
        end;
      end;
    begin
      if not VarIsArray(Value) then
      begin
        Result := Item(Value);
      end
      else
      begin
        JSONArray := TJSONArray.Create;
        for i := 0 to Length(Value) do
        begin
          JSONArray.AddElement(Item(Value[i]));
        end;
        Result := JSONArray;
      end;
    end;