Android Question Http POST with token and JSON parameters [SOLVED]

ThePuiu

Active Member
Licensed User
Longtime User
I'm trying to call a password change method from an API. A token is used for authentication. The parameters that the method expects are:
B4X:
{
  "OldPassword": "sample string 1",
  "NewPassword": "sample string 2",
  "ConfirmPassword": "sample string 3"
}

I tried to make a POST using the code:
B4X:
    Dim j As HttpJob
    j.Initialize("",Me)
    Dim values As Map
    values.Initialize

    values.Put("OldPassword","Parola_01")
    values.Put("NewPassword","Parola_02")
    values.Put("ConfirmPassword","Parola_02")
  
    Dim JsonList As List
    JsonList.Initialize
    JsonList.add(values)
    
    Dim JSONGenerator As JSONGenerator
    JSONGenerator.Initialize2(JsonList)

Log(JSONGenerator.ToString())
    
    j.PostString("http://servername.ro/api/account/changepassword",JSONGenerator.ToString())
    j.GetRequest.SetHeader("Authorization","Bearer " & Main.Token)

but I receive the following message:
ResponseError. Reason: Bad Request, Response: {"Message":"The request is invalid.","ModelState":{"model.OldPassword":["The Current password field is required."],"model.NewPassword":["The New password field is required."]}}
and Log is: [{"OldPassword":"Parola_01","NewPassword":"Parola_02","ConfirmPassword":"Parola_02"}]

Can you help me with an idea?
 

OliverA

Expert
Licensed User
Longtime User
The API is expecting a map and you are sending it a list containing a map
 
Upvote 0

ThePuiu

Active Member
Licensed User
Longtime User
Tried with:
B4X:
j.PostMultipart("http://serername.ro/api/account/changepassword",values,Null)
but the response is: ResponseError. Reason: Unsupported Media Type, Response: {"Message":"The request entity's media type 'multipart/form-data' is not supported for this resource."}
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The API is expecting a map and you are sending it a list containing a map
I should have been more specific: The API expects an JSON Map, not a JSON List. Try:
B4X:
    Dim j As HttpJob
    j.Initialize("",Me)
    Dim values As Map = CreateMap("OldPassword": "Parola_01", "NewPassword": "Parola_02", "ConfirmPassword": "Parola_02")
  
    Dim JSONGenerator As JSONGenerator
    JSONGenerator.Initialize(values) ' Initialize will turn a B4X map to a JSON map, Initialize2 will turn a B4X list to a JSON list
    
    Log(JSONGenerator.ToString())
    
    j.PostString("http://servername.ro/api/account/changepassword",JSONGenerator.ToString())
    j.GetRequest.SetHeader("Authorization","Bearer " & Main.Token)
 
Upvote 0

ThePuiu

Active Member
Licensed User
Longtime User
response: ResponseError. Reason: Bad Request, Response: {"Message":"The request is invalid.","ModelState":{"model.OldPassword":["The Current password field is required."],"model.NewPassword":["The New password field is required."]}}

JSONGenerator is empty...
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
JSONGenerator is empty...
Huh? Are you sure you used the code posted above? No list is involved, nor is Initialize2 used. Testing this code (just an abbreviated version of above):
B4X:
Dim values As Map = CreateMap("OldPassword": "Parola_01", "NewPassword": "Parola_02", "ConfirmPassword": "Parola_02")
  
Dim JSONGenerator As JSONGenerator
JSONGenerator.Initialize(values) ' Initialize will turn a B4X map to a JSON map, Initialize2 will turn a B4X list to a JSON list
    
Log("JSON:")
Log(JSONGenerator.ToString())
Produces the desired result:
JSON:
{"NewPassword":"Parola_02","OldPassword":"Parola_01","ConfirmPassword":"Parola_02"}
 
Upvote 0

ThePuiu

Active Member
Licensed User
Longtime User
Copy /paste
LOG: {"OldPassword":"Parola_01","NewPassword":"Parola_02","ConfirmPassword":"Parola_02"}
but same response:
ResponseError. Reason: Bad Request, Response: {"Message":"The request is invalid.","ModelState":{"model.OldPassword":["The Current password field is required."],"model.NewPassword":["The New password field is required."]}}
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Looks like someone else was having the same issue as you are having here. The sad part is, they really don't spell out how they fixed it. Going by the recommendations of others in that thread you could try:
B4X:
Dim j As HttpJob
j.Initialize("",Me)
Dim values As Map = CreateMap("OldPassword": "Parola_01", "NewPassword": "Parola_02", "ConfirmPassword": "Parola_02")

Dim encodedValues As String = UrlEncodeMap(values)
Log(encodedValues)  
    
j.PostString("http://servername.ro/api/account/changepassword",encodedValues)
j.GetRequest.SetHeader("Authorization","Bearer " & Main.Token)

I've seen a few sites that have their responses in JSON, but they take URL encoded data for input (which is something that was recommended in the above mentioned posting).

Link to UrlEncodeMap: https://www.b4x.com/android/forum/threads/b4x-urlencodemap.118626/

Note: You may also need to add
B4X:
j.GetRequest.SetContentType("application/x-www-form-urlencoded")
to your request
 
Upvote 0
Top