Skip to content
David Arno edited this page Jan 25, 2017 · 2 revisions

JSON Serialization

Serialize/deserialize Succinc<T> types to JSON


Introduction to JSON Serialization

So as not to cause the core Succinc<T> package to be dependent on JSON.Net, this support is provided via a separate nuget package, SuccincT.Json. This latter package provides all of the core Succinc<T> functionality, plus JSON serialization support.

The Succinc<T> types are serialized via their own custom JsonConverter and ContractResolver types. These types are invoked passing new settings details to JSON.Net serialize and deserialize methods.

Using a single type JsonConverter

If you, for example, only need to convert Union<T1,T2> to JSON and back, you can provide that JsonConverter to the SerializeObject and DeserializeObject methods:

var settings = new JsonSerializerSettings();
settings.Converters.Add(new UnionOf2Converter());

var union = new Union<List<int>, string>(new List<int> { 1, 2 });
var json = SerializeObject(union, settings);
var newUnion = DeserializeObject<Union<List<int>, string>>(json, settings);

A new JsonSerializerSettings is created, specifying the UnionOf2Converter. This JsonSerializerSettings object is then passed as a parameter to SerializeObject and DeserializeObject.

The mapping of types to converters is as follows:

Maybe<T> OptionConverter
None NoneAndUnitConverter
Option<T> OptionConverter
ValueOrError ValueOrErrorConverter
Union<T1,T2> UnionOf2Converter
Union<T1,T2,T3,T4> UnionOf3Converter
Union<T1,T2,T3,T4> UnionOf4Converter
Unit NoneAndUnitConverter

Using SuccinctContractResolver

If you are using more than one Succinc<T> type, having to specify the converter each time is not ideal. To assist with this, SuccincT.Json also includes a ContractResolver, that knows about all of the converters. Again, this is supplied to the SerializeObject and DeserializeObject methods via the settings parameter:

class TestCollection
{
    public Option<int> Value1 { get; set; }
    public None Value2 { get; set; }
    public Union<int, string> Value3 { get; set; }
}

...

var settings = new JsonSerializerSettings
{
    ContractResolver = SuccinctContractResolver.Instance
};
var value = new TestCollection
{
    Value1 = Option<int>.Some(1),
    Value2 = none,
    Value3 = new Union<int, string>("a")
};
var json = SerializeObject(value, settings);
var newValue = DeserializeObject<TestCollection>(json, settings);

Using DefaultSettings

JSON.Net supports defining settings just once at the start of an application by providing JsonConvert.DefaultSettings with a Func<JsonSerializerSettings> delegate. You can use this property to supply JSON.Net with the required ContractResolver or JsonConverter just once and then the settings parameter is no longer needed:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    ContractResolver = SuccinctContractResolver.Instance
};

...

class TestCollection
{
    public Option<int> Value1 { get; set; }
    public None Value2 { get; set; }
    public Union<int, string> Value3 { get; set; }
}

...

var value = new TestCollection
{
    Value1 = Option<int>.Some(1),
    Value2 = none,
    Value3 = new Union<int, string>("a")
};
var json = SerializeObject(value);
var newValue = DeserializeObject<TestCollection>(json);