Fork on Github
Download the Nuget package
The last tutorial focused on parsing embedded JSON objects. This time, we’ll focus on serialising simple objects in C#.
Object serialisation using JSON# is 25 times to several hundred times faster than serialisation using JSON.NET, on a quad-core CPU with 16GB RAM. The source code is written in a BDD-manner, and the associated BDD features contain performance tests that back up these figures.
Let’s start with a basic class in C#:
class SimpleObject { public string Name { get; set; } public int Count { get; set; } }
Our first step is to provide serialisation metadata to JSON#. Traditionally, most frameworks use Reflection to achieve this. While this works very well, it requires the component to know specific assembly metadata that describes your object. This comes with a slight performance penalty.
Ideally, when leveraging Reflection, the optimal design is a solution that reads an object’s assembly metadata once, and caches the result for the duration of the application’s run-time. This is generally not achievable with stateless HTTP calls. Using Reflection, we will likely query the object’s assembly during each HTTP request when serialising or de-serialising an object, suffering the associated performance-overhead for each request.
JSON# allows us to avoid that overhead by exposing serialisation metadata in the class itself:
class SimpleObject : IHaveSerialisableProperties { public string Name { get; set; } public int Count { get; set; } public virtual SerialisableProperties GetSerializableProperties() { return new SerialisableProperties("simpleObject", new List<JsonProperty> { new StringJsonProperty { Key = "name", Value = Name }, new NumericJsonProperty { Key = "count", Value = Count } }); } }
First, we need to implement the IHaveSerialisableProperties
interface, allowing JSON# to serialise our object. Notice the new method, GetSerializableProperties
, that returns a SerialisableProperties
object, which looks like this:
public class SerialisableProperties { public string ObjectName { get; set; } public IEnumerable<JsonProperty> Properties { get; private set; } public IEnumerable<JsonSerialisor> Serialisors { get; set; } public SerialisableProperties(IEnumerable<JsonProperty> properties) { Properties = properties; } public SerialisableProperties(IEnumerable<JsonSerialisor> serialisors) { Serialisors = serialisors; } public SerialisableProperties(string objectName, IEnumerable<JsonProperty> properties) : this(properties) { ObjectName = objectName; } public SerialisableProperties(string objectName, IEnumerable<JsonSerialisor> serialisors) : this(serialisors) { ObjectName = objectName; } public SerialisableProperties(IEnumerable<JsonProperty> properties, IEnumerable<JsonSerialisor> serialisors) : this(properties) { Serialisors = serialisors; } public SerialisableProperties(string objectName, IEnumerable<JsonProperty> properties, IEnumerable<JsonSerialisor> serialisors) : this(properties, serialisors) { ObjectName = objectName; } } }
This object is essentially a mapper that outlines how an object should be serialised. Simple types are stored in the Properties property, while more complex types are retrieved through custom JsonSerialisor
objects, which I will discuss in the next tutorial. The following code outlines the process involved in serialising a SimpleObject
instance:
First, we initialise our object
var simpleObject = new SimpleObject {Name = "Simple Object", Count = 10};
Now initialise a BinaryWriter
, setting the appropriate Encoding. This will be used to build the object’s JSON-representation, under-the-hood.
var writer = new BinaryWriter(new MemoryStream(), new UTF8Encoding(false));
Now we use our Json
library to serialise the object
var serialisableProperties = simpleObject.GetSerializableProperties(); byte[] serialisedObject; using (var serialisor = new StandardJsonSerialisationStrategy(writer)) { Json.Serialise(serialisor, new JsonPropertiesSerialisor(serialisableProperties)); serialisedObject = serialisor.SerialisedObject; }
Below is the complete code-listing:
var simpleObject = new SimpleObject {Name = "Simple Object", Count = 10}; var writer = new BinaryWriter(new MemoryStream(), new UTF8Encoding(false)); var serialisableProperties = simpleObject.GetSerializableProperties(); byte[] serialisedObject; using (var serialisor = new StandardJsonSerialisationStrategy(writer)) { Json.Serialise(serialisor, new JsonPropertiesSerialisor(serialisableProperties)); serialisedObject = serialisor.SerialisedObject; }
Now our serialisedObject
variable contains a JSON-serialised representation of our SimpleObject
instance, as an array of raw bytes. We’ve achieved this without Reflection, by implementing a simple interface, IHaveSerialisableProperties
in our SimpleObject
class, and have avoided potentially significant performance-overhead; while a single scenario involving reflection might involve very little performance-overhead, consider a web application under heavy load, leveraging Reflection. We can undoubtedly support more concurrent users per application tier if we avoid Reflection. JSON# allows us to do just that.
In the next tutorial, I’ll discuss serialising complex objects.
Connect with me:
Hi,
I tried to install the package from the nuget manager console but it said it is incompatible with 4.0 framework. I got a local copy from github. Could you please tell me how to install it manually?
Hi Sean, you can add the project to your solution in Visual Studio and then add it as a project reference to your application:
https://msdn.microsoft.com/en-us/library/f3st0d45.aspx