It is currently 23 January 2020, 11:51 Advanced search

[How-To] Using DO Classes to read/write JSON

Questions and answers on how to best use Instant Developer

[How-To] Using DO Classes to read/write JSON

Postby ljwilson » 19 August 2019, 21:49

A few months ago I inherited a c# library used to make REST calls to a fairly robust web service. I imported the DLL into InDe and had to add wrapper functions on the c# side so it would return IDArray objects, but other than that it worked fairly well.

If the library had been completed that would have been that, but we started needing to add more functionality to it and pretty soon it became obvious development time would go a lot faster if we replaced the c# library with native InDe code. Plus if I wanted to use the same code in an Inde Java Project then I wouldn't have to rewrite the library for it.

The bulk of the library was just creating corresponding classes for all the JSON elements that the webservice used--so if I could mirror that in InDe then the rest was to just use getHTTP calls with the appropriate JSON.

After google-translating a bit from the Italian side and some trial and error, here is the methodology I used:
  1. Create DO classes from JSON (two methods)
    1. If you only want classes and have no need for saving class data to the database or display data in panels, you can use the Built-In Tools - Web API Importer. The trick is to go to the Generic tab, and type simple JSON objects in the response field. You do NOT have to fill-in any other fields. You can then import them and save them with the class (tag) name. By simple objects I mean just one level, and no array elements. Example:
      Code: Select all
      {
        "Title": "Abc",
        "Quantity": 1,
        "Price": 99.99,
        "IsGood:": true,
        "DateCreated:": "2019-08-19"
      }

      Notice how it determines the data type from the values. Give the class a name, and click the create button. It will create (if you don't already have one) a component and put the class in it. This was designed for IOT, but works for this as well.
      2019-08-19_15-36-05.png
      2019-08-19_15-36-05.png (183.97 KiB) Viewed 766 times
    2. It would be nice if InDe had a way to drag existing classes to a database to create corresponding tables/fields just like you can drag tables to create create classes. But until it does, another way of doing this is to use a SQL Server script which will take existing JSON and convert it into SQL Create
      Table statements. I found one on github: https://github.com/cornerstoneedge/apiexplorer-sample-create-event-session-csharp This script requires SQL Server 2017 or higher. It could use a bit of tweaking to work with InDe a little better, but its current form is usable as-is. It will also handle fairly complex (nested) JSON. See the attached example program where I created the SQL Server db tables/fields from the create statements this script generated. I then imported the tables into InDe.
  2. But if you created the db tables first, before dragging the tables to the app or component to create the corresponding DO Classes, first setup your parent/child/foreign key relationships in the database. This way your classes will be able to figure out the master/detail relationships when you drag them to panels.
  3. Either way, once you have the classes--for nested objects, drag children into parents as collections.
  4. JSON parsing into classes is case-sensitive, by the CODE of the class. I've found it doesn't matter on the collection properties, but it does matter on the other properties. I usually make the name and code match whatever the web service with which I'm working uses. It is possible to ignore case by using reflection in global My Document Helper xml events, but the CODE would still have to match the JSON tag regardless of case (unless you translate it in those same XML events).
  5. I found an issue with the JSON I had to use for this REST service--it has a enum field which uses the tag "__type" (no quotes, and two underscores precede it). Apparently double-underscores at the beginning of a field can be an issue with c#. In my case I could not load the JSON into classes (or an XML doc for that matter) unless I translated the two underscores into anything else. So I use string replace to translate from __type to ___type before loading, and when saving translate back from ___type to __type to match what the REST service expects.
  6. The last trick is converting the JSON created by saving classes to JSON for collections of single elements which need to represented as a single JSON object (i.e. no [ ]; not an array). Fortunately we can make use of InDe's isArrayChild property. To use it requires loading the JSON created from the classes back into a new xmldoc object, then selecting on the nodes in question, setting those nodes' isArrayChild property to false, then saving the XML doc back to JSON. Once again the attached example program has an example.

Other items of note:
  • I use this web-based JSON formatter: https://jsonformatter.org
  • The example app uses the NewtonSoft JSON.net library https://www.newtonsoft.com/json only for pretty-printing the JSON displayed to the user.
  • In the example app I have checked the "exclude from debug" option for the Global Document Load/Save XML Entity/Prop events in the My Document Helper so you can use the debugger on the example app without seeing all of the calls for it. Uncheck that option as needed.
  • The classes have extra id fields in them since I used the second method of creating the db tables first. These are ignored in reading/writing JSON.
  • The My Document Helper Global Document Save XML Prop event removes the do_ and _O fields so they don't show in the JSON.
  • For the Rest Classes database, fill-in your local db connection information if you need to--since the app doesn't actually access the database it isn't required to run, but of course to import tables from a SQL database where you run the script to create them you would have to have valid connection info.
Rest Client Express.zip
Created with InDe 19.0 r6 Express
(775.08 KiB) Downloaded 97 times


Enjoy!

...jack
ljwilson
 
Posts: 502
Joined: 26 November 2013, 14:15

Re: [How-To] Using DO Classes to read/write JSON

Postby john w » 20 August 2019, 16:00

Jack - thanks for the detailed write up and the project sample I have downloaded that my collection of InDe reference material.

It is really helpful for you have shared this.
Regards

John W
User avatar
john w
 
Posts: 604
Joined: 24 October 2012, 16:29
Location: Apple Valley, Minnesota USA

Re: [How-To] Using DO Classes to read/write JSON

Postby lucabaldini » 10 October 2019, 8:54

Just a word: WOW! :-)))))

I like the idea
drop a class (that is not already connected with a database table) onto a database to create the corresponding "database object (tables & fields)" that will contain that document and all its pubblic fields


Why don't you suggest it into our CRM? It seems pretty simple but I'm sure it would help when you start from documents and classes (maybe because you are using WebAPI) and want to save documents into your DB.

Thanks a lot!
User avatar
lucabaldini
Pro Gamma
Pro Gamma
 
Posts: 3848
Joined: 1 October 2010, 17:03
Location: Bologna

Re: [How-To] Using DO Classes to read/write JSON

Postby ljwilson » 10 October 2019, 12:45

Good idea--I just added it to the CRM (PRP000531).

Thanks!

...jack
ljwilson
 
Posts: 502
Joined: 26 November 2013, 14:15


Return to Tips & Tricks

Who is online

Users browsing this forum: antonio.pavan and 4 guests