Question
· Feb 16, 2016

Manage data types with %ZEN.proxyObject and Ens.Util.JSON.ObjectToJSONStream()

Hello,

I am trying to use %ZEN.proxyObject to send out in JSON format so I do:

    set tProxyRequest = ##class(%ZEN.proxyObject).%New()
    set tProxyRequest.notanumber = "28001"
    set tProxyRequest.aboolean = "true"
    
    set tBody = ##class(%GlobalCharacterStream).%New()
    do ##class(Ens.Util.JSON).ObjectToJSONStream(tProxyRequest,.tBody,"aelotwu")
    w tBody.Read()

and I get:

{
        "aboolean":"true",
        "notanumber":28001
}

But I want this:

{
        "aboolean":true,
        "notanumber":"28001"
}

 

Help please !

Discussion (10)2
Log in or sign up to continue

Stefan. I used a registered class with typed properties and doesn't works frown

I made this test class:

Class test.DummyClass Extends %RegisteredObject
{

Property notanumber As %String;

Property aboolean As %Boolean;

Method outout2JSON()
{
    set tProxyRequest = ##class(%ZEN.proxyObject).%New()
    set tProxyRequest.notanumber = ..notanumber
    set tProxyRequest.aboolean = ..aboolean
    
    set tBody = ##class(%GlobalCharacterStream).%New()
    do ##class(Ens.Util.JSON).ObjectToJSONStream(tProxyRequest,.tBody,"aelotwu")
    w tBody.Read()
}

ClassMethod Test()
{
    set dummy = ##class(test.DummyClass).%New()
    set dummy.notanumber = "28001"
    set dummy.aboolean = 1
    do dummy.outout2JSON()
}

}

And this is the result sad:

USER>do ##class(test.DummyClass).Test()
{
        "aboolean":1,
        "notanumber":28001
}
USER>w $zv
Cache for Windows (x86-64) 2015.2.1 (Build 705U) Mon Aug 31 2015 16:45:59 EDT

 

What's wrong?

Thanks

I modified your code like this:

Class test.DummyClass Extends %RegisteredObject
{

Property notanumber As %String;

Property aboolean As %Boolean;

/// do ##class(test.DummyClass).Test()
ClassMethod Test()
{
    
    set dummy = ..%New()
    set dummy.notanumber = "28001"
    set dummy.aboolean = 1
    do ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(dummy,,,"aelotw")
}
}

Terminal output:

>do ##class(test.DummyClass).Test()
{
        "notanumber":"28001",
        "aboolean":true
}

Thanks Eduard for posting the working solution. The reason why this works is that you actually create an object of your registered class and assign the values. The jsonProvider API can now walk the object and project the types properly.

In the non-working example, you created a zenProxyObject and assigned the values on your own. The zenProxyObject just deals with auto-types and guesses the best possible type fit. As you see, this guess can't be correct all the time as in this case.

If you want to create a JSON structure with specific types, either use a) the new JSON support in 2016.1 (recommended if 2016.1 is available) or b) create a subclass from %RegisteredObject and use the jsonProvider API.

PERFECT !!

I see now my mistake smiley

I fixed the code like this:

Class test.DummyClass Extends %RegisteredObject
{
Property notanumber As %String;
Property aboolean As %Boolean;
Method outout2JSON()
{
    set tBody = ##class(%GlobalCharacterStream).%New()
    do ##class(Ens.Util.JSON).ObjectToJSONStream(##this,.tBody,"aelotw")
    w tBody.Read()
}
ClassMethod Test()
{
    set dummy = ##class(test.DummyClass).%New()
    set dummy.notanumber = "28001"
    set dummy.aboolean = 1
    do dummy.outout2JSON()
}
}
 

And now:

USER>do ##class(test.DummyClass).Test()
{
        "notanumber":"28001",
        "aboolean":true
}