Android Question [Solved] Post JSON to MS Web API

MarkusR

Well-Known Member
Licensed User
Longtime User
[solved]
Hello,
i have a client app at phone (b4a) and a web server with iis and a vs studio 2017 web api project.

i will post data as json to server (i used okhttputils2) and the server should deserialize the data into a object/class.

but i facing the problem that nothing is deserialized and the class/object is empty there :(

i made a html page with form post and this works fine (today but not now^^)!?

the code in web api looks like this
B4X:
MyClass Template()
{
 return new (MyClass)
}

it ouput something like this, so i thought i can put the same in ..
{"FailureId":0,"FailureDateTime":"2018-03-20T19:19:27.4971098+01:00","CompanyId":0,"UserId":0,"UserName":null,"Location":null,"Trouble":null,"Note":null,"GPS_LATITUDE_DEGREE":0.0,"GPS_LONGITUDE_DEGREE":0.0,"GPS_ALTITUDE_METER":0.0}

here i have the problem that data propertys are empty when i send a json via post from b4a app
B4X:
SaveData(MyClass data)
{
 //...
}

i am not sure
this html form works but i will using a app
(just a example not the real one)
B4X:
<html>
<body>
<form action="https://user:password@domain/myfunction/" method="Post">
Datum:<br>
<input name="FailureDateTime" type="text" value="03-20-2018 15:01">
<input name="UserName" type="text" value="Markus">
<input name="Location" type="text" value="Mülheim">
<input name="Trouble" type="text" value="Drucker">
<input name="Note" type="text" value="Note">
<input type="submit" value="Submit">
</form>
</body>
</html>

this is the sending part in b4a app
B4X:
Sub Send() As Boolean

    Dim D As String
    DateTime.DateFormat = "dd/MM/yyyy"
    DateTime.TimeFormat = "HH:mm:ss"
    D = DateTime.Date(DateTime.Now) & "T" & DateTime.Time(DateTime.Now)

    Dim Map1 As Map
    Map1.Initialize
    Map1.Clear

    Map1.Put("FailureId",0)
    Map1.Put("FailureDateTime",D)
    Map1.Put("CompanyId",0)
    Map1.Put("UserId",0)
    Map1.Put("UserName",EditTextUserName.Text)
    Map1.Put("Trouble",EditTextTrouble.Text)
    Map1.Put("Note",EditTextNote.Text)
    Map1.Put("Location",EditTextLocation.Text)
    Map1.Put("GPS_ALTITUDE_METER",0.0)
    Map1.Put("GPS_LATITUDE_DEGREE",0.0)
    Map1.Put("GPS_LONGITUDE_DEGREE",0.0)

    '------------ Prüfen

    If Map1.Get("UserName")="" Then
        ToastMessageShow("Name eingeben ..",False)
        Return False
    End If
 
    If Map1.Get("Trouble")="" Then
        ToastMessageShow("Problem eingeben ..",False)
        Return False
    End If

    If Map1.Get("Location")="" Then
        ToastMessageShow("Ort eingeben ..",False)
        Return False
    End If
 
    '------------

    Dim JSON As JSONGenerator
    JSON.Initialize(Map1)
 
    Dim data As String =   JSON.ToPrettyString(1) ' JSON.ToString()
 
    Log(data)
 
    Dim Job As HttpJob
    Job.Initialize("Job1",Me)
    Job.Username="..."
    Job.Password="..."
    Job.PostString("https://domain/myfunction" , data )

    Return True

End Sub

Sub JobDone (Job As HttpJob)
 
   Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
   If Job.Success = True Then
       Select Job.JobName
           Case "Job1"

               Log(Job.GetString)
               If Job.GetString.StartsWith(Chr(34) & "OK" & Chr(34) ) Then 'das ist ja mal Panne^^
                   ToastMessageShow(Job.GetString,True)
                   StartActivity(ActivityThanks)
                   Activity.Finish
               Else
                   ButtonSend.Enabled=True
                   ToastMessageShow("Error: " & Job.GetString, True)
               End If
           Case "JobTemplate"
               Log(Job.GetString)
       End Select
   Else
       ButtonSend.Enabled=True
       Log("Error: " & Job.ErrorMessage)
       ToastMessageShow("Error: " & Job.ErrorMessage, True)
   End If
   Job.Release
 
End Sub
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
But the HTML form that you are showing is not posting JSON, it's posting an url encoded string in the body of the post. And what code are you using in your B4A app to post whatever you are trying to get to the server? What return response are you getting from the server? Is the server returning a 200 status code (Job.Success = True) and the error message is in Jog.GetString or is the server returning a non 200 status code (Job.Success = False) and the error message is in Job.ErrorMessage?
 
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
as you say, hmm, yes, html did not send json. thanks for this hint.
the httpjob got success state and also my OK return from server and i got empty recordsets in database for any reason.
tomorrow i will see what firefox network protocol log. i guess if me send the same from b4a it will work.
now my html page form send did not work, it make also empty records.
maybe i using linktosql wrong im c# i need to run this web api in debug mode.
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
httpjob got success state
Job.Success = True has no relationship to success/non-success of your database entry, UNLESS the web API that you are using makes it so. All that Job.Success = True means is that the HTTP status code was in the 200 range. Depending on your API, even a failed update can (and for the most part does) return a HTTP status code of 200. It is up to you then to check whatever was returned (in this case, what is in Job.GetString) to see if there was an error or not.
 
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
i searched a little bit in web
it seems i need send as
ContentType: "application/json"
is this possible with okhttputils2?

i found it , it need okhttp lib
B4X:
Job.GetRequest.SetContentType("application/json")
 
Last edited:
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
i solved it today :)

B4X:
    Dim JSON As JSONGenerator
    JSON.Initialize(Map1)
        
    Dim data As String =   JSON.ToPrettyString(1)
        
    Dim Job As HttpJob
    Job.Initialize("Job1",Me)
    Job.Username="..."
    Job.Password="..."
    
    Job.PostString("https://blah.com/name" , data )
    Job.GetRequest.SetContentType("application/json") ' okhttp lib
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Job.GetRequest.SetContentType("application/json") '
is not okhttp lib, but HTTP
No. Using okhttputils you need to add okhttp

From http.xml (http lib)
<ide_comment>Deprecated - Replaced by OkHttp</ide_comment>
 
Upvote 0

luciano deri

Active Member
Licensed User
Longtime User
i have okhttputils2 and okhttp, but Job.GetRequest.SetContentType("application/json") is a unknown object

With httputils2 and http is ok
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
i have okhttputils2 and okhttp, but Job.GetRequest.SetContentType("application/json") is a unknown object
B4A Version: 8.30
Parse den Code. (0.00s)
Kompiliere den Code. (0.01s)
Kompiliere Layoutcode. (0.00s)
Organisiere Libraries. (0.00s)
Generiere R Datei. (0.06s)
Kompiliere generierten Java Code. (0.57s)
Byte-Code konvertieren - optimiert dex. (1.72s)
Packe Dateien. (0.18s)
Kopieren von Bibliothek Ressourcen (0.00s)
Signiere Paketdatei (privater Key). (0.40s)
ZipAlign file. (0.06s)
Installiere Datei auf Gerät. Error
Kein Gerät gefunden.

So it does compile fine here. With okhttp lib.
 

Attachments

  • okhttptest.zip
    8 KB · Views: 431
Upvote 0
Top