JSON Serialization
CodeCarvings Piczard V1.2 Help
JSON Serialization
Send Feedback
Other Features > JSON Serialization

Glossary Item Box

CONTENTS

  1. Introduction
  2. Serialization
  3. Deserialization
  4. How to develop a class that can be serialized and deserialized into/from JSON

 

Please see the examples:

  • A.305 - "Web - PictureTrimmer / Load & save images and values"
  • A.306 - "Web - PictureTrimmer / Load & save images and values (SQL Server)"
  • A.503 - "Web - Image Upload Demos / SimpleImageUpload Control / Usage example #2"
  • A.505 - "Web - Image Upload Demos / SimpleImageUpload Control / Usage example #4 (SQL Server)"
  • A.506 - "Web - Image Upload Demos / SimpleImageUpload Control / Usage example #5"

 

 

1. Introduction

The CodeCarvings.Piczard.Serialization namespace contains classes and interfaces that allow to serialize and deserialize objects into/from JSON (JavaScript Object Notation).

This allows to easily save the current state of an object (such as PictureTrimmerValue) and then reload it.

Almost every ImageProcessingFilter and FormatEncoderParams class contained in Piczard can be serialized/deserialzied.

An important thing to know is that the serialization process includes an intermediate step.

In this intermediate step the original object is first transformed into a graph (composed by instances of the JSONElement class).
A second (optional) step encodes the graph to string.

Moreover you can directly create a graph or alter an existing one.
In this way you can have full control over the serialization process.

The following is the list of types that can be used to build the graph:

The JSONSerializer class provides useful methods for the serialization process.

 

 

2. Serialization

If you want to serialize an object you can use one one of the following methods:

In order to be serialized, the object must be of a class that implements the IJSONSerializable interface (for example the object can be an instance of the ImageProcessingFilter).
However the above methods accept also:

Example:

Serialization example Copy Code
ImageTransformation myFilter = new ImageTransformation(120F, 90F, false, false);
string result = JSONSerializer.SerializeToString(myFilter);

Some overloads of the serialization methods (such as Serialize(Object,JSONSerializationOptions,Boolean)) accept additional parameters that allow to configure the behaviour of the JSONSerializer.
In most cases you don't need to use these parameters, however you can pass them to force the JSONSerializer to serialize additional information about the source object such as:

  • The name of the Type of the object (with or without assembly qualified name).
  • The version of the algorithm used by the object (and each sub-object) to serialize itself.

 

 

3. Deserialization

The JSONSerializer class provides the method Deserialize that allows to transform a string (or a JSONObject) back to its original state of object.

As for the serialization process, also the deserialization process includes an intermediate step.
In case a string is passed as source to the Deserialize method, the string is first transformed into a graph (composed by instances of the JSONElement class), and then the "real" deserialization process takes place.

It is important to note that, in order to work, the Deserialize method needs to know the Type of the object to deserialize.

This information can be obtained by JSONSerializer class in different ways:

  1. The Type can be passed as parameter to one of the following methods:
  2. The type can be passed to one of the following generic methods:
  3. The type name can be read directly from the JSON string or the JSONObject *.
    * Please note that this is possible only if the JSON string (or the JSONObject) contains this information.
    By default, this is not true.
    In order to serialize the type name it is necessary to pass the parameter serializeType=true when the object is serialized (for example SerializeToString(myObject, true))

Once the Type is obtained, the Deserialize method uses the reflection to try to instantiate a new object.
For this purpose, the Deserialize method tries to invoke a static method having name "FromJSON" (StaticFactoryMethodName) on that Type.
The JSONObject to be deserialized is passed as parameter to the static method.

Since reflection is a computing-intensive operation, it is suggested - if possible - to deserialize the JSON source by directly invoking the static FromJSON method of the Type to deserialize.

Example:

Deserialization example Copy Code
ImageTransformation myFilter1 = JSONSerializer.Deserialize<ImageTransformation>(myJSONString);
ImageTransformation myFilter2 = ImageTransformation.FromJSON(myJSONString);

The above example code contains two equivalent alternatives.
The second one is the suggested choice.

 

 

4. How to develop a class that can be serialized and deserialized into/from JSON

Please see the MyRotationFilter class contained in the ~/App_Code folder of ExampleSet A

In order to develop a class that can be serialized and deserialized into/from JSON the following two requirements are necessary:

  1. Serialization: The class must implement the IJSONSerializable interface.
  2. Deserialization: The class must contain a static method having name "FromJSON" (StaticFactoryMethodName) able to deserialzie a JSONObject (passed to it as parameter).

 

Serialization

The IJSONSerializable interface contains the following members:

Deserialization

The public static method FromJSON must be able to deserialie a JSONObject (passed to it as parameter).

The classes provided by Piczard contain also an overload of the method that accept a string as parameter.
Even if it is not required to add this overload to your classes, it is suggested to do so.
Please see the following example.

 

A JSON serializable class Copy Code
public class MySerializableClass
   : IJSONSerializable
{
   
public MySerializableClass()
   {
   }
   
int IJSONSerializable.SerializationVersion
   {
       get
       {
           
// Default version = 1
           
return 1;
       }
   }
   JSONSerializationException IJSONSerializable.GetSerializationException()
   {
       
// No error
       
return null;
   }
   JSONObject IJSONSerializable.ToJSONObject(JSONSerializationOptions options)
   {
       
// Options cannot be null
       
if (options == null)
       {
           options = JSONSerializationOptions.Default;
       }
       
// *** Put here your code to serialize the object ***
       
// Add some values
       
JSONObject result = options.GetNewJSONObject(this);
       result.SetNumberValue(
"foo1", 1);
       result.SetBoolValue(
"foo2", true);
       result.SetStringValue(
"foo3", "Test");
       
// Add an array
       
JSONArray bar1 = new JSONArray();
       bar1.AddNumberValue(1);
       bar1.AddNumberValue(2);
       bar1.AddNumberValue(3);
       result.SetArray(
"bar1", bar1);
       
// Add a sub-object
       
JSONObject baz1 = new JSONObject();
       baz1.SetNumberValue(
"qux1", 1);
       baz1.SetBoolValue(
"qux2", true);
       baz1.SetStringValue(
"qux3", "Test");
       result.SetObject(
"baz1", baz1);
       
// *********
       
return result;
   }
   
// Deserialize from version 1
   
private static MySerializableClass FromJSON_1(JSONObject jsonObject)
   {
       
if (jsonObject == null)
       {
           
return null;
       }
       MySerializableClass result =
new MySerializableClass();
       
// *** Put here your code to de-serialize the object ***
       
// Get the values
       
int? foo1 = jsonObject.GetNumberInt32Value("foo1");
       
bool? foo2 = jsonObject.GetBoolValue("foo2");
       
string foo3 = jsonObject.GetStringValue("foo3");
       
// Get the array
       
JSONArray bar1 = jsonObject.GetArray("bar1");
       
for (int i = 0; i < bar1.Count; i++)
       {
           
int? barValue = bar1.GetNumberInt32Value(i);
       }
       
// Get the sub-object
       
JSONObject baz1 = jsonObject.GetObject("baz1");
       
if (baz1 != null)
       {
           
int? qux1 = jsonObject.GetNumberInt32Value("qux1");
           
bool? qux2 = jsonObject.GetBoolValue("qux2");
           
string qux3 = jsonObject.GetStringValue("qux3");
       }
       
// *********
       
return result;
   }
   
public static MySerializableClass FromJSON(JSONObject jsonObject)
   {
       
if (jsonObject == null)
       {
           
return null;
       }
       
// Check the version
       
int version = jsonObject.GetSerializationVersion();
       
switch (version)
       {
           
case 1:
               
return FromJSON_1(jsonObject);
       }
       
// Invalid serialization version
       
throw new JSONInvalidObjectException(typeof(MyRotationFilter));
   }
   
// Deserialize from string
   
public static MySerializableClass FromJSON(string jsonString)
   {
       
return FromJSON(JSONObject.Decode(jsonString));
   }
}
©2013 Sergio Turolla. All Rights Reserved.