Delphi TJson.ObjectToJsonString(TFoo): exclude private variables from the json string - json

I have an object eg.:
TFoo = class(TObject)
private
FConnection : TADOConnection;
public
FName : string;
FSurname : string;
end;
i convert this object in a json string with ObjectToJsonString, eg.:
uses REST.Json;
// ...
var
aFoo : TFoo;
begin
aFoo := TFoo.create;
Memo1.lines.text := TJson.ObjectToJsonString(aFoo);
aFoo.free;
end;
TJson.ObjectToJsonString make a json string with both private and public variables.
i want exclude some variable like FConnection from the json string (it expose also the connection string).
Any suggestion for allow the json conversion only on the public variable?

Use the JSONMarshalled attribute:
Attribute that specifies whether a field or type should be marshalled and unmarshalled.
If JSONMarshalledAttribute is not present in a field or type, that field or type should be marshalled and unmarshalled. If JSONMarshalledAttribute is present but is False, the marshalling and unmarshalling processes skip that field or type.
For example:
type
TFoo = class(TObject)
private
[JSONMarshalled(False)]
FConnection : TADOConnection;
public
FName : string;
FSurname : string;
end;
Also look at the JSONName attribute. By default, if a field name begins with an F character, marshaling strips off the F in the resulting JSON data. In your example above, this is fine, so that FName and FSurname are marshalled as Name and Surname. But this may not always be desirable, so you can use JSONName to specify your own field names in the JSON data, eg:
type
TFoo = class(TObject)
private
[JSONMarshalled(False)]
FConnection : TADOConnection;
public
Name : string;
Surname : string;
[JSONName('FullName')]
FullName : string;
end;

Related

JSON reader Kotlin

How can I read JSON file into more than one documents and save it in Mongo DB.
I have two models:
#Document
data class Person(val name: String){
#Id
private val id : String? = null
And:
#Document
data class Floor (private var floorName: StoreyEnum,
private val roomNumber: String
private val personID: String){
#Id
private val id : String? = null}
I have JSON file in which I have fields to both models. Moreover I want connect this documents with "relation", how can I do that?
Use Gson if it's on a JVM backend.
BTW, I don't quite get your purpose of making id private, val, and initialized to null at the same time. Because in that way it's always set to null, never changed and never read. so I changed it to this:
data class Person(val name: String, private val id: String? = null)
Then you can use Gson to encode and parse the object:
fun main(args: Array<String>) {
val gson = Gson()
val person = Person("name", "0")
println(person)
val personJson = gson.toJson(person)
println(personJson)
val parsedPerson = gson.fromJson(personJson, Person::class.java)
println(parsedPerson)
}
Output:
Person(name=name, id=0)
{"name":"name","id":"0"}
Person(name=name, id=0)

Kotlin: 'val' on secondary constructor parameter is not allowed

I have following class:
class Person(val name: String) {
private var surname: String = "Unknown"
constructor(name: String, surname: String) : this(name) {
this.surname = surname
}
}
But when I want to have the name parameter immutable in second constructor:
constructor(val name: String, surname: String) : this(name) {
this.surname = surname
}
I have the following compile-time error:
Kotlin: 'val' on secondary constructor parameter is not allowed
Can someone explain why is Kotlin compiler not allowing to do this?
Parameters in Kotlin are always immutable. Marking a constructor parameter as a val turns it into a property of a class, and this can only be done in the primary constructor, because the set of properties of a class cannot vary depending on the constructor used to create an instance of the class.
In addition to the great answer of yole, the documentation is pretty clear as well:
Note that parameters of the primary constructor can be used in the initializer blocks. They can also be used in property initializers declared in the class body.
[...] In fact, for declaring properties and initializing them from the primary constructor, Kotlin has a concise syntax:
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
Much the same way as regular properties, the properties declared in the primary constructor can be mutable (var) or read-only (val).
This all does not apply to secondary constructors.
You can define the variable as val or var in the class you inherit from
open class Human(val name: String) constructor(name: String) {
open fun showInfo()
{
println("Show Info")
}
}
class Person:Human {
constructor(name: String) : super(name)
private var surname: String = "Unknown"
override fun showInfo() {
println("$name And surname is $surname")
}
}
The currently accepted answer is correct in explaining why your initial attempt did not work. As such, given your particular scenario, I would inverse the solution and make your secondary constructor the primary, and make that second parameter have a default value.
class Person(val name: String, private var surname: String = "Unknown")
Also, if the class's purpose is to simply hold data, I would make it a data class to improve its handling.

Golang JSON Marshal/Unmarshal on struct containing byte arrays [duplicate]

type TestObject struct {
kind string `json:"kind"`
id string `json:"id, omitempty"`
name string `json:"name"`
email string `json:"email"`
}
func TestCreateSingleItemResponse(t *testing.T) {
testObject := new(TestObject)
testObject.kind = "TestObject"
testObject.id = "f73h5jf8"
testObject.name = "Yuri Gagarin"
testObject.email = "Yuri.Gagarin#Vostok.com"
fmt.Println(testObject)
b, err := json.Marshal(testObject)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(b[:]))
}
Here is the output:
[ `go test -test.run="^TestCreateSingleItemResponse$"` | done: 2.195666095s ]
{TestObject f73h5jf8 Yuri Gagarin Yuri.Gagarin#Vostok.com}
{}
PASS
Why is the JSON essentially empty?
You need to export the fields in TestObject by capitalizing the first letter in the field name. Change kind to Kind and so on.
type TestObject struct {
Kind string `json:"kind"`
Id string `json:"id,omitempty"`
Name string `json:"name"`
Email string `json:"email"`
}
The encoding/json package and similar packages ignore unexported fields.
The `json:"..."` strings that follow the field declarations are struct tags. The tags in this struct set the names of the struct's fields when marshaling to and from JSON.
Ru it on the playground.
When the first letter is capitalised, the identifier is public to any
piece of code that you want to use.
When the first letter is lowercase, the identifier is private and
could only be accessed within the package it was declared.
Examples
var aName // private
var BigBro // public (exported)
var 123abc // illegal
func (p *Person) SetEmail(email string) { // public because SetEmail() function starts with upper case
p.email = email
}
func (p Person) email() string { // private because email() function starts with lower case
return p.email
}
In golang
in struct first letter must uppercase
ex. phonenumber -> PhoneNumber
======= Add detail
First, I'm try coding like this
type Questions struct {
id string
questionDesc string
questionID string
ans string
choices struct {
choice1 string
choice2 string
choice3 string
choice4 string
}
}
golang compile is not error and not show warning. But response is empty because something
After that, I search google found this article
Struct Types and Struct Type Literals
Article then... I try edit code.
//Questions map field name like database
type Questions struct {
ID string
QuestionDesc string
QuestionID string
Ans string
Choices struct {
Choice1 string
Choice2 string
Choice3 string
Choice4 string
}
}
Is work.
Hope for help.

Getting Values of a JSON Object in vb.net

EDITED:
I got stuck while getting value of a JSON object in vb.net. My JSON request posts data like given below:
function submitEmail() {
var ClientsPersonalInfo = {
FullName: $("#FullName").val(),
PhoneNumber: $("#PhoneNumber").val(),
EmailAddress: $("#EmailAddress").val(),
DOB: $("#DOB").val(),
Occupation: $("#Occupation").val(),
NINumber: $("#NINumber").val(),
FullAddress: $("#FullAddress").val()
}
var ClientsData = {};
ClientsData.ClientsPersonalInfo = ClientsPersonalInfo;
var d = '{"ClientsData":' + JSON.stringify(ClientsData) + '}'
$.ajax({
type: "POST",
url: "add-new-client.aspx/SubmitEmail",
data: d,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response)
},
failure: function (msg) {
alert(msg);
}
});
}
JSON Object Looks Like
{
"ClientsPersonalInfo": {
"FullName": "",
"PhoneNumber": "",
"EmailAddress": "",
"DOB": "",
"Occupation": "",
"NINumber": "",
"FullAddress": ""
}
}
The above request returns an object in vb.net
VB Code:
<WebMethod()> _
Public Shared Function SubmitEmail(ByVal ClientsPersonalInfo As Object) As String
// What to do next to get object "ClientsPersonalInfo"
// I want to access properties of the object like
//Dim name As String = ClientsPersonalInfo.FullName
Return "Successfully Converted."
End Function
No I want to get values of this object and needs to append in a table. Please guide me how to get values of the above object?
First make sure your Json is in valid format using jsonlint
Then generate class base on it using jsonutils
Public Class ClientsPersonalInfo
Public Property FullName As String
Public Property PhoneNumber As String
Public Property EmailAddress As String
Public Property DOB As String
Public Property Occupation As String
Public Property NINumber As String
Public Property FullAddress As String
End Class
Public Class ClientsVehicleInfo
Public Property DrivingLicense As String
Public Property VehicleMakeModel As String
Public Property VehicleColour As String
Public Property PolicyNumber As String
Public Property TypeOfCover As String
Public Property VehicleStoredIn As String
End Class
Public Class ClientsData
Public Property ClientsPersonalInfo As ClientsPersonalInfo
Public Property ClientsVehicleInfo As ClientsVehicleInfo
End Class
Public Class ClientData
Public Property ClientsData As ClientsData
End Class
Use Newtonsoft JSON to deserialize your Json into object(s) then you may simply access its properties value. (remember to add Json.net to your project using Manage NuGet Packages)
Imports Newtonsoft.Json
Dim obj = JsonConvert.DeserializeObject(Of Dictionary(Of String, ClientsData))(yourJsonString)
At least one problem is not using Option Strict On. The code at fault:
Shared Function SubmitEmail(ByVal ClientData As Object) As String
Dim obj = JsonConvert.DeserializeObject(Of NewClientData)(ClientData)
If you turn on Option Strict that will not compile because JsonConvert.DeserializeObject takes a string argument. I am not sure why the exception (image now removed) seems to come from VB rather than Newtonsoft, but that isnt helping.
Your deserialized object will also just disappear when it goes out of scope when the method ends.
Applicable to Edit #9
The error mentioning a Dictionary seems misleading and probably something internal relating to how the properties are collected (many times json can be deserialized to a Dictionary(Of String, String). Given the json posted (with data):
{
"ClientsData": {
"ClientsPersonalInfo": {
"FullName": "Ziggy Le Strange",
"PhoneNumber": "505050",
"EmailAddress": "ziggy#foobar.com",
"DOB": "",
"Occupation": "Freelancer",
"NINumber": "7",
"FullAddress": "123 Easy street"
}
}
}
There are actually 3 classes: ClientsPersonalInfo with the data, ClientsData which is a class containing that one and in previous edits also included a ClientsVehicleInfo class.
But there is yet another class represented by the enclosing {...}. The robots who can create the classes for you name it Example or RootObject. In this case, I would call it ClientContainer.
This works:
' the outermost {}
Public Class ClientContainer
Public Property ClientsData As ClientsData
End Class
Public Class ClientsPersonalInfo
Public Property FullName As String
Public Property PhoneNumber As String
Public Property EmailAddress As String
Public Property DOB As String
Public Property Occupation As String
Public Property NINumber As String
Public Property FullAddress As String
End Class
Public Class ClientsData
Public Property ClientsPersonalInfo As ClientsPersonalInfo
Public Property ClientsVehicleInfo As ClientsVehicleInfo
End Class
Public Class ClientsVehicleInfo
' whatever it is supposed to hold
End Class
To deserialize the data (you may have to adapt it for web use, Shared seems incorrect to me):
' pass in the json AS STRING
' returns JUST the ClientsPersonalInfo
Public Function GetClientData(jsonData As String) As ClientsPersonalInfo
' you must use the container class
Dim client = JsonConvert.DeserializeObject(Of ClientContainer)(jsonData )
' TEST:
Console.WriteLine(client.ClientsData.ClientsPersonalInfo.FullName)
Return client.ClientsData.ClientsPersonalInfo
End Function
ClientsData seems to be an unneeded layer. The container could hold both of the other objects directly. If this is meant to hold info for more than one client, you would have keys in place of "ClientsData": in the json (e.g. "ziggy":{}, "zacky":{}, "zoey":{}.
Output:
Ziggy Le Strange
Since, as per comment, that vehicle info is part of the deal, you can change it to return ClientsData which holds both the Personal and Vehicle info:
Public Function GetClientData(jsonData As String) As ClientsData
' you must use the container class
Dim client = JsonConvert.DeserializeObject(Of ClientContainer)(jsonData )
Return client.ClientsData
Turn on Option Strict
Dont box parameters or returns As Object, they loose some of their meaning.
Keep in mind that the outermost braces in json represent a container object
Also, storing a Date as string looks bad too.

Golang - pass struct as argument to function

I have to parse some nested JSON, which translates into a Go type, like this:
type Config struct {
Mail struct {
From string
To string
Password string
}
Summary struct {
Send bool
Interval int
}
}
Now I want to call a function for each key (Mail, Summary), I tried it like this:
utils.StartNewMailer(config.Mail)
The problem is, how do I construct the called function, I tried to mirror the Mail struct (and called it mailConfig), since I can't pass an arbitrary struct as an argument.
func StartNewMailer(conf mailConfig){ //..., but that doesn't work either, I get the following compiler error message:
cannot use config.Mail (type struct { From string; To string; Password string }) as type utils.mailConfig in argument to utils.StartNewMailer
Do I have to pass in every single value to the called function or is there a nicer way to do this?
utils.mailConfig fields should be exported, as in the literal struct field in Config type.
type mailConfig struct {
From string
To string
Password string
}
I suggest declaring inner structs as types themselves instead of using struct literals.
type Mail struct {
From string
To string
Password string
}
type Summary struct {
Send bool
Interval int
}
type Config struct {
Mail
Summary
}
func StartNewMailer(Mail mailConfig)