0

I need to prepare JSON and send it to a website. I am using TJSONObject. My code is simple:

procedure TForm1.Button1Click(Sender: TObject);
var 
  JsonArray,JsonArray1:TJSONArray;
  F,F1:TJSONObject;
begin
  FJSONObject.AddPair('api_password','password');
  FJSONObject.AddPair('method','POST');

  F:=TJSONObject.Create;
  F.AddPair('nest1','v1');
  F.AddPair('nest2','v2');
  JsonArray:=TJSONArray.Create;
  JsonArray.AddElement(F);
  FJSONObject.AddPair('Main array',JsonArray);
end;

As a result I've got this JSON:

{
  "api_password": "password",
  "method": "POST",
  "Main array": [
    {
      "nest1": "v1",
      "nest2": "v2"
    }
  ]
}

But, according to the website`s API, I need to send this JSON instead:

{
  "api_password": "password",
  "method": "POST",
  "Main array": [
    {
      \"nest1\": \"v1\",
      \"nest2\": \"v2\"
    }
  ]
}

How can I make this JSON?

7
  • 2
    TJSONObject.ToString automatically adds escape characters where needed. I don't have a deep knowledge about that but I think that your site's API doesn't expect a standard JSON string Commented May 17, 2018 at 13:10
  • Guy from website sad that array of second level in json structure has to be protected by “\” in other case can`t parser json string Commented May 17, 2018 at 13:13
  • 2
    @DmytroLendel I think you are either misreading the API doc, or the doc is wrong. If the website admins say the doc is not wrong, and the example shown is what they are really expecting, then the website has a faulty JSON parser, because the example is not legal per the JSON spec. Strings cannot have their opening/closing " characters escaped as shown. Only " characters inside of strings can be escaped. Commented May 17, 2018 at 18:25
  • 1
    Is their API doc public? If so, why did you not include it? Commented May 17, 2018 at 23:06
  • yes. it`s public but not in English glaz.systems/api-emulator# Commented May 18, 2018 at 8:55

1 Answer 1

2

Instead of adding an object to JsonArray you need to add a string. At that point, when generating a string from FJSONObject, it will automatically replace all " with \". However, this will only work if F does not contain any ", otherwise F.ToString must be replaced with F.ToString.Replace ('\"', '"' ). You also need to handle F lifetime, because it is no longer handled by FJSONObject.

procedure TForm1.Button1Click(Sender: TObject);
var
  JsonArray : TJSONArray;
  F : TJSONObject;
begin
  FJSONObject.AddPair('api_password', 'password');
  FJSONObject.AddPair('method', 'POST');
  F := TJSONObject.Create;
  try
    F.AddPair('nest1', 'v1');
    F.AddPair('nest2', 'v2');
    JsonArray := TJSONArray.Create;
    JsonArray.Add(F.ToString);
    FJSONObject.AddPair('Main array', JsonArray);
  finally
    F.Free;
  end;
end;

Unfortunately what you want is not a standard JSON format and you can't easily generate it. If you add a string to FJSONObject, it will be automatically treated with ". Same for all elements of the array, if you add the array directly. So there's always something to be replaced manually and when generating the result, you also need to use this line.

FJSONObject.ToString.Replace('["{', '[{').Replace('}"]', '}]')
Sign up to request clarification or add additional context in comments.

5 Comments

As shown, TJSONArray.Add(F.ToString) will produce ["{\"nest1\":\"v1\",\"nest2\":\"v2\"}"] instead of [{\"nest1\":\"v1\",\"nest2\":\"v2\"}] like the OP is asking for. The " characters between the [{ and }] sequences would have to be stripped off manually.
ToString does not add \" :-(
Solution is JsonArray.Add(ReplaceStr( F.ToString,'"','\"')); I checked result and seems it`s ok
@Dmytro Lendel I don't think, that could work, it will just create \\" from \".
@RemyLebeau Thanks, I missed that, I've already updated the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.