Search code examples
delphiurlrestdelphi-xe2datasnap

Delphi datasnap RESTful URL if contain parameter with character T/F/Y/N will convert to boolean True and False


I have a server method "CustomerLookup" that accept a string parameter "CompanyName", user may enter any characters and CustomerLookup method will return a list of customers that partially match the criteria. My REST URL is something like below, the final word "t" is the method's parameter

http://localhost/datasnap/rest/TSales_SM/CustomerLookup/t

My expected outcome is if user enter "t", method will return all customers' companyname that partially match "t". But i found out for certain character like T & Y will convert to True, N & F will convert to false. The converting code is implemented in delphi unit -> DataSnap.DSService

procedure TDSRESTService.BuildParamArray(const Params: TStringList; var ParamArray: TJSONArray);
  var
    I: Integer;
    S: String;
    LValue: Double;
  begin
    ParamArray := TJSONArray.Create;
    for I := 0 to Params.Count - 1 do
    begin
      S := Params[I];
      if (AnsiIndexText(S,TrueBoolStrs) > -1) then
         ParamArray.AddElement(TJSONTrue.Create)
      else if AnsiIndexText(S,FalseBoolStrs) > -1 then
         ParamArray.AddElement(TJSONFalse.Create)
      else if AnsiCompareStr(S,NULL) = 0 then
         ParamArray.AddElement(TJSONNull.Create)
      else
         if TDBXPlatform.TryJsonToFloat(S, LValue) then
           ParamArray.AddElement(TJSONNumber.Create(S))
         else
           ParamArray.AddElement(TJSONString.Create(S));
    end;
  end;

Can anyone tell me how to prevent system to convert of T, F, Y, N to true and false

Thanks.


Solution

  • I think there must be some where in your code define something like:

    SetLength(TrueBoolStrs, 4);
    TrueBoolStrs[0] := 'True';
    TrueBoolStrs[1] := 'T';
    TrueBoolStrs[2] := 'Yes';
    TrueBoolStrs[3] := 'Y';
    
    SetLength(FalseBoolStrs, 4);
    FalseBoolStrs[0] := 'False';
    FalseBoolStrs[1] := 'F';
    FalseBoolStrs[2] := 'No';
    FalseBoolStrs[3] := 'N';
    

    A workaround solution would be patch TDSRestService.BuildParamArray to:

    procedure TDSRESTService.BuildParamArrayPatch(const Params: TStringList;
      var ParamArray: TJSONArray);
    const NULL = 'null';
    var
      I: Integer;
      S: String;
      LValue: Double;
    begin
      ParamArray := TJSONArray.Create;
      for I := 0 to Params.Count - 1 do
      begin
        S := Params[I];
        if SameText(S, 'true') then
          ParamArray.AddElement(TJSONTrue.Create)
        else if SameText(S, 'false') then
          ParamArray.AddElement(TJSONFalse.Create)
        else if AnsiCompareStr(S, NULL) = 0 then
          ParamArray.AddElement(TJSONNull.Create)
        else if TDBXPlatform.TryJsonToFloat(S, LValue) then
          ParamArray.AddElement(TJSONNumber.Create(S))
        else
          ParamArray.AddElement(TJSONString.Create(S));
      end;
    end;