jsonlinuxserializationvala

JSON Serialize - Modify Resulting Property Name


I am trying to use this library to serialize a class I wrote. Valadoc : gobject_to_data.

Suppose I have a class written like this:

public class MyObject : Object {
    public string property_name { get; set; }

    public MyObject (string str) {
        this.property_name = property_name;
    }
}

public static int main (string[] args) {
    MyObject obj = new MyObject ("my string");

    string data = Json.gobject_to_data (obj, null);
    print (data);
    print ("\n");

    return 0;
}

The output I see is:

{
  "property-name" : "my string"
}

What I want to do is modify the property name to instead be in "Snake case":

{
  "property_name" : "my string"
}

How can I do that?

I have tried implementing serialize_property from the Serializable interface like this:


public class MyObject : Object : Json.Serializable {
     public string property_name { get; set; }

     public MyObject (string str) {
    this.property_name = property_name;
     }

     public Json.Node serialize_property(string property_name, Value value, ParamSpec pspec) {
        string property_name_camel_case = property_name.replace("-", "_");

        Json.Node value_node = new Json.Node(Json.NodeType.VALUE);
        value_node.set_value(value);

        Json.Object final_object = new Json.Object();
        final_object.set_member(property_name_camel_case, value_node);

        return value_node;
    }
}

public static int main (string[] args) {
    MyObject obj = new MyObject ("my string");

    string data = Json.gobject_to_data (obj, null);
    print (data);
    print ("\n");

    return 0;
}

However, I still receive this output:

{
  "property-name" : "my string"
}

Solution

  • Answer in case anyone else is looking for this

    Unfortunately, JSON serialization does not support non-canonical names see here. When you are implementing Json.Serializable.list_properties, you still cannot create any kind of ParamSpec with a non-canonical name.

    Because of this, I had to resort to building a Json.Object and manually setting each of the key-value pairs myself like this:

        public string to_json() {
            // None of these names are canonical, so we have to write them manually
            Json.Object main_object = new Json.Object();
            main_object.set_string_member("@type", "setTdlibParameters");
            main_object.set_string_member("database_directory", database_directory);
            main_object.set_boolean_member("enable_storage_optimizer", enable_storage_optimizer);
    
            Json.Node wrapper = new Json.Node(Json.NodeType.OBJECT);
            wrapper.set_object(main_object);
    
            Json.Generator generator = new Json.Generator();
            generator.set_root(wrapper);
    
            return generator.to_data(null);
        }