Android Question post json error

red30

Well-Known Member
Licensed User
Longtime User
I am trying to send a json file, but I get an error: “ResponseError. Reason: Bad Request, Response: <h1> Bad Request (400) </h1> "
Moreover, if I send the same file via postman, everything comes up fine.
jtest.png

Here is my code:
B4X:
    Dim fd As MultipartFileData
    fd.Initialize
    fd.KeyName = "data"
    fd.Dir = File.DirInternal
    fd.FileName = "1.json"
    fd.ContentType = "application/json"
    j.PostMultipart("link", CreateMap("data": "1.json"), Array(fd))
    j.GetRequest.SetContentType("multipart/form-data")
What am I doing wrong?
 

red30

Well-Known Member
Licensed User
Longtime User
Here is a request for a PHP to which the server responds normally. Maybe she will add clarity ...
PHP:
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => XXX,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array('data '=> new CURLFILE('XXX.json')),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Basic XXX'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Try this
B4X:
Dim j As HttpJob
j.Initialize("", Me)
Dim basicAuth As String = "username:password"
Dim su As StringUtils
Dim authInfo = su.EncodeBase64(basicAuth.GetBytes("UTF8"))
Dim fd As MultipartFileData
fd.Initialize
fd.KeyName = "data"
fd.Dir = File.DirInternal
fd.FileName = "1.json"
'fd.ContentType = "application/json"
'All the examples that you given so far use  application/octet-stream  as the encoding
fd.ContentType = "application/octet-stream"
'j.PostMultipart(link, CreateMap("data": "1.json"), Array(fd))
'The second parameter in PostMultipart sets the URL query string. None of
'your examples use one.
j.PostMultipart(link, Null, Array(fd))
'j.GetRequest.SetContentType("multipart/form-data")
'Let the B4A library set the content type header for this POST.
'Nothing special is set in the PHP example, so let's not do anything in B4A
j.GetRequest.SetHeader("Cookie", "csrftoken=XXX")
j.GetRequest.SetHeader("Authorization", "Basic "&authInfo)
    
Wait For (j) JobDone(j As HttpJob)
If j.Success Then
    Log(j.GetString)
End If
j.Release
 
Upvote 0

red30

Well-Known Member
Licensed User
Longtime User
Looks like you do need to upload a file. Have you tried to upload the file without the key / value map?
Try this
B4X:
Dim j As HttpJob
j.Initialize("", Me)
Dim basicAuth As String = "username:password"
Dim su As StringUtils
Dim authInfo = su.EncodeBase64(basicAuth.GetBytes("UTF8"))
Dim fd As MultipartFileData
fd.Initialize
fd.KeyName = "data"
fd.Dir = File.DirInternal
fd.FileName = "1.json"
'fd.ContentType = "application/json"
'All the examples that you given so far use  application/octet-stream  as the encoding
fd.ContentType = "application/octet-stream"
'j.PostMultipart(link, CreateMap("data": "1.json"), Array(fd))
'The second parameter in PostMultipart sets the URL query string. None of
'your examples use one.
j.PostMultipart(link, Null, Array(fd))
'j.GetRequest.SetContentType("multipart/form-data")
'Let the B4A library set the content type header for this POST.
'Nothing special is set in the PHP example, so let's not do anything in B4A
j.GetRequest.SetHeader("Cookie", "csrftoken=XXX")
j.GetRequest.SetHeader("Authorization", "Basic "&authInfo)
  
Wait For (j) JobDone(j As HttpJob)
If j.Success Then
    Log(j.GetString)
End If
j.Release
Thank you so much OliverA and Erel! I spent all day trying different options, but only this code worked:
B4X:
Dim j As HttpJob
j.Initialize("", Me)
Dim basicAuth As String = "username:password"
Dim su As StringUtils
Dim authInfo = su.EncodeBase64(basicAuth.GetBytes("UTF8"))
Dim fd As MultipartFileData
fd.Initialize
fd.KeyName = "data"
fd.Dir = File.DirInternal
fd.FileName = "1.json"
'fd.ContentType = "application/json"
'fd.ContentType = "application/octet-stream"
j.PostMultipart(link, CreateMap("data": "1.json"), Array(fd))
'or j.PostMultipart(link, Null, Array(fd))
'j.GetRequest.SetContentType("multipart/form-data")
j.GetRequest.SetHeader("Authorization", "Basic "&authInfo)
Wait For (j) JobDone(j As HttpJob)
If j.Success Then
    Log(j.GetString)
End If
j.Release
And it doesn't matter what is specified in fd.ContentType and key / value map, the main thing is not to specify j.GetRequest.SetContentType ("multipart / form-data") and everything works. This is very strange and not obvious, since in postman I just specify “form-data” in the Body. I don't fully understand why this works, but now it works!
 
Upvote 0
Top