iOS Question Map to Json problem with boolean value

StxTeam

Member
Licensed User
Hi,
in debug mode i have a problem in creation of a Json from Map

My code

B4X: Copy
    WebApiAuthBase.Put("IsAdmin",False)
    WebApiAuthBase.Put("Roles",Null)
    WebApiAuthBase.Put("License",Null)
    WebApiAuthBase.Put("Modules",Null)
    WebApiAuthBase.Put("Auths",Null)
    WebApiAuthBase.Put("Factory",Null)
    WebApiAuthBase.Put("Module",Null)
    WebApiAuthBase.Put("Area",Null)
    WebApiAuthBase.Put("Geo",Null)
    WebApiAuthBase.Put("Version",Vers_AppCore_Code)
    WebApiAuthBase.Put("CallerType",1)

    Dim json As JSONGenerator
    json.Initialize(WebApiAuthBase)
    Log(json.ToString)

this code return this json:
{"IsAdmin":0,"CallerType":1,"Version":"1.8.6"}

but the right json should be:
{"IsAdmin":False,"CallerType":1,"Version":"1.8.6"}

The same code in B4a work fine with some difference, Json.ToString in B4a include also Null value.

I didn't test code in release mode.

Thanks everybody for a solution.
 
I did not notice similar problem.
Meanwhile my program writes JSONs and (when reads). checks type of object

Your test works fine also (at least in current B4I release)
Code: Copy
   Dim WebApiAuthBase As Map
    WebApiAuthBase.Initialize    
    
    WebApiAuthBase.Put("Roles",     Null)
    WebApiAuthBase.Put("IsAdmin",   False)
    WebApiAuthBase.Put("License",  Null)
    WebApiAuthBase.Put("Modules",    Null)
    WebApiAuthBase.Put("Auths",     Null)
    WebApiAuthBase.Put("Factory",   Null)
    WebApiAuthBase.Put("Module",    Null)
    WebApiAuthBase.Put("Area",      Null)
    WebApiAuthBase.Put("Geo",       Null)
    WebApiAuthBase.Put("Version",   "Vers_AppCore_Code")
    WebApiAuthBase.Put("CallerType", 1)

    Dim jsonGenerator As JSONGenerator    
    jsonGenerator.Initialize (WebApiAuthBase)        
    Log (jsonGenerator.ToString)

Output:
{"IsAdmin":false,"CallerType":1,"Version":"Vers_AppCore_Code"}
 
Upvote 0
Also working correctly here (B4I 6.00 in debug mode)
{"IsAdmin":False,"CallerType":1,...

Anyhow, if you parse the produced json into a Map and read again that field (which contains an integer) into a boolean, it will give True if the value is <>0 and false otherwise

Very dirty workaround if you need to deliver the JSON string with the correct 'true' and 'false' ?
Code: Copy
  Dim WebApiAuthBase As Map
    WebApiAuthBase.Initialize    
    
Dim myFalse as String = "myFalse"
Dim myTrue as String = "myTrue"

    WebApiAuthBase.Put("IsAdmin",   myFalse)
    WebApiAuthBase.Put("IsAdmin2",   myTrue)
    WebApiAuthBase.Put("Roles",     Null)
    WebApiAuthBase.Put("License",  Null)
    WebApiAuthBase.Put("Modules",    Null)
    WebApiAuthBase.Put("Auths",     Null)
    WebApiAuthBase.Put("Factory",   Null)
    WebApiAuthBase.Put("Module",    Null)
    WebApiAuthBase.Put("Area",      Null)
    WebApiAuthBase.Put("Geo",       Null)
    WebApiAuthBase.Put("Version",   "Vers_AppCore_Code")
    WebApiAuthBase.Put("CallerType", 1)

    Dim jsonGenerator As JSONGenerator    
    jsonGenerator.Initialize (WebApiAuthBase)      

   Log(jsonGenerator.ToString)
   Dim dirtyWorkaroundCorrectedString as String = jsonGenerator.ToString.Replace( $""myFalse""$, "false").Replace($""myTrue""$, "true")
  
   Log (dirtyWorkaroundCorrectedString)
 
Upvote 0
In my program I do not use any workaround.
When I create a JSON, I write jsonGenerator.ToString to file.

Further I read a file (as string) and initialize jsonParser. Like here:
Code: Copy
    Dim WebApiAuthBase As Map
    WebApiAuthBase.Initialize    
    
    WebApiAuthBase.Put("Roles",     Null)
    WebApiAuthBase.Put("IsAdmin",   False)
    WebApiAuthBase.Put("License",  Null)
    WebApiAuthBase.Put("Modules",    Null)
    WebApiAuthBase.Put("Auths",     Null)
    WebApiAuthBase.Put("Factory",   Null)
    WebApiAuthBase.Put("Module",    Null)
    WebApiAuthBase.Put("Area",      Null)
    WebApiAuthBase.Put("Geo",       Null)
    WebApiAuthBase.Put("Version",   "Vers_AppCore_Code")
    WebApiAuthBase.Put("CallerType", 1)

    Dim jsonGenerator As JSONGenerator    
    jsonGenerator.Initialize (WebApiAuthBase)        
    Dim stringInput As String = jsonGenerator.ToString
    
    Dim jsonParser As JSONParser
    jsonParser.Initialize (stringInput)
    Dim root As Map = jsonParser.NextObject
    Dim IsAdmin As Object = root.Get("IsAdmin")
    If IsAdmin Is Int Then Log ("Int")
    If IsAdmin Is Boolean Then Log ("Boolean")

As you can see, IsAdmin remains Boolean. Probably, something happens if to save Map to file (instead of string).
 
Upvote 0
My vers. B4I 6.30,

i send this json to a webserver, with wireshark i got the same result
{"IsAdmin":0,"CallerType":1,"Version":"1.8.6"}

I get this result by my test, if i brake code, in debug windows the map structure is right, and also log give me right as wireshark, but if i execute code without brake, i got the problem.

I will try in release.
 
Upvote 0
I try it in release mode, but it doen't work, the same as debug mode.

I try to reproduce it in a small program.

I let you know soon.
 
Upvote 0
Here my test project, same result.

But if i try to comment a line in sub "InizializeWebApiAuthBase" without clearing Project ("CTRL+P" ) it works fine.

Any idea?

Thanks everybody.
 

Attachments

Upvote 0
Yes, strange. Try to add to Process_Globals
Code: Copy
Public Const myTrue  As Boolean = True
Public Const myFalse As Boolean = False

and replace False, True to myFalse, myTrue.
 
Last edited:
Upvote 0
As I wrote, the underlying type system doesn't support real booleans. They are represented with numbers.

Not very nice but works:
Code: Copy
Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    
    Private MyMap As Map
    Private JSONTrue = "~~~true~~~", JSONFalse = "~~~false~~~", JSONNull = "~~~null~~~" As String
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
    MakeJson
End Sub

Sub MakeJson
    Dim JSON As JSONGenerator
    
    If MyMap.IsInitialized = False Then
        InizializeWebApiAuthBase
    End If
    
    JSON.Initialize(MyMap)
    Log(JSONToString(JSON))
End Sub

Sub JSONToString(jg As JSONGenerator) As String
    Return jg.ToPrettyString(4).Replace($""${JSONTrue}""$, "True").Replace($""${JSONFalse}""$, "False").Replace($""${JSONNull}""$, "Null")
End Sub

'Inizialize WebapiAuth base
Sub InizializeWebApiAuthBase
    
    MyMap.Initialize
    MyMap.Put("Culture","en-GB")
    MyMap.Put("IsLogged",JSONTrue)
    MyMap.Put("UserLogin",JSONNull)
    
    MyMap.Put("UserPK",JSONNull)

    MyMap.Put("IsAdmin",JSONFalse)
    MyMap.Put("Roles",JSONNull)
    MyMap.Put("License",JSONNull)
    MyMap.Put("Modules",JSONNull)
    MyMap.Put("Auths",JSONNull)
    MyMap.Put("Factory",JSONNull)
    MyMap.Put("Module",JSONNull)
    MyMap.Put("Area",JSONNull)
    MyMap.Put("Geo",JSONNull)
    MyMap.Put("Version","1.8.6")
    MyMap.Put("CallerType",1) 
End Sub
 
Upvote 0
Thanks Erel it works. Do you thinks there'll be a solution in future, a nice solution ? ? Because our app must work with an IIS webapi and it doesn't accept 0 or 1 as boolean.
 
Upvote 0
Found the solution to this problem. It is only when adding a boolean value directly to a collection(list, map, etc.), the json serializer converts the boolean value to 0s and 1s. If the boolean value is set to a boolean variable and then added to a collection is then serialized correctly.

Code: Copy
Dim mBool as Boolean = True
myMap.put("boolvalue", mBool)

Code: Copy
mMap.put("booleanvalue", True.as(Boolean))

works perfectly.
 
Upvote 0
Back
Top