Delphi XE5:JSON从客户端发送TRESTRequest Body作为text / plain接收

时间:2015-12-05 16:35:50

标签: json delphi delphi-xe5 rest-client

我正在尝试从客户端使用RESTClient(Delphi XE5,Windows 8)发送JSON。但在服务器端,它以文本/纯文本形式接收。

我想发送的JSON:

{
  "kind": "News",
  "group": {
    "id": "G01"
  },
  "title": "Latest News",
  "content": "this is the latest news"
}

在服务器端收到:

    ----------120515234155952
    Content-Disposition: form-data; name="body"
    Content-Type: text/plain
    Content-Transfer-Encoding: quoted-printable

    {
      "kind": "News",
      "group": {
        "id": "G01"
      },
      "title": "Latest News",
      "content": "this is the latest news"
    }
    ----------120515234155952
    Content-Disposition: form-data; name="access_token"
    Content-Type: text/plain
    Content-Transfer-Encoding: quoted-printable

    ya29.QQKUa6ZDsco2uDK2neuYdurolLF8LAPDjMZGTdF3bnDLOIgX1JQ8g-FxKtMLSF-gl=
    MDY
    ----------120515234155952--

用于将JSON添加到TRESTRequest的代码:

var
  ........
  RESTRequest : TESTRequest;
  content : String;
  ........
begin

  ........

  content:='{'+
        '  "kind": "News",'+
        '  "group": {'+
        '    "id": "G01"'+
        '  },'+
        '  "title": "Latest News",'+
        '  "content": "this is the latest news"'+
        '}';
  RESTRequest.Params.AddItem('body',content,TRESTRequestParameterKind.pkREQUESTBODY,[],ctAPPLICATION_JSON);

  ............

end;

我尝试使用其他变体而没有任何变化:

  1. RESTRequest.AddBody(Content);
  2. RESTRequest.AddBody(TJSONObject.ParseJSONValue(Content));
  3. RESTRequest.AddBody(TJSONObject.ParseJSONValue(Content),ctAPPLICATION_JSON);
  4. RESTRequest.AddBody(TJSONObject.ParseJSONValue(UTF8String(Content)),ctAPPLICATION_JSON);
  5. 我发现在执行DoPrepareRequestBody方法时(在unit REST.Client上找到)TCustomRESTRequest只能使用LParam.NameLParam.Value来调用MultipartPeerStream.AddFormField。这意味着contentType始终为空,MultiPartPeerStream将其转换为text / plain。

    有没有办法强制其内容类型为application/json

3 个答案:

答案 0 :(得分:3)

您可以尝试使用TJSONObject来组成正文:

var
  jsResponse: TJSONValue;
  jsRequest: TJSONObject;

begin
  jsRequest := TJSONObject.Create();
  jsRequest.AddPair('UserName', lbledtUser.Text);
  jsRequest.AddPair('Password', lbledtPwd.Text);
  RESTRequest.AddBody(jsRequest);
  jsRequest.Free();
  RESTRequest.Execute();
  jsResponse := RESTRequest.JSONValue;

在服务器端,内容类型符合预期:

var
  jsReq: TJSONValue;
...
begin
...
    if (CompareText(Request.ContentType, 'application/json') = 0) then
    begin
      jsReq := TJSONObject.ParseJSONValue(s);
    end;

答案 1 :(得分:1)

您可以使用它来强制内容类型:

  RESTClient1.Params.AddItem('Content-Type','application/json', TRESTRequestParameterKind.pkREQUESTBODY, [], TRESTContentType.ctAPPLICATION_JSON);

答案 2 :(得分:0)

对我来说,解决方案是在请求中设置参数:

RESTRequest1.AddParameter('Content-Type', 'application/json', TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
RESTRequest1.AddParameter('Accept', 'application/json', TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);