Skip to content

ThirdPartySerialization

Daniel Gonzalez Garcia edited this page Jun 20, 2017 · 8 revisions

Third Party Serialization

Serialization for third party libraries (those not included in the .NET framework) is supported via separate NuGet packages (one per library) that provide the source code needed to customize the serialization process.

NOTE: the process and artifacts needed is different for each library. A different section will be provided for each library.

Json.NET

NMoneys JsonNET Nuget

NuGet version

Once the package is installed, there are available three custom converters

  • CanonicalMoneyConverter
  • DefaultMoneyConverter
  • NumericalMoneyConverter

Each converter can be configured as per Json.NET configuration instructions:

  • pass the converter as an optional parameter to either.SerializeObject()or .DeserializeObject() static methods of JsonConvert
  • Use the .Converters collection of a JsonSerializerSettings instance that will be passed to any of the aforementioned methods

If Json-NET is used by a framework/library, refer to that library documentation on how to customize serialization/deserialization. Or you can drop a line in the discussion group in case someone can give a hand.

CanonicalMoneyConverter

This converter processes the same input/output as the built-in JSON serialization of the library when using the built-in DataContractJsonSerializer: an Amount numeric property and a Currency object with a three-letter code (by default) IsoCode property.

Property casing must be configured outside this converter, for example, using a different implementation of DefaultContractResolver.

{"Amount" : 123.4, "Currency" : {"IsoCode" : "XXX"}}

DefaultMoneyConverter

This converter produces a standard representation of a monetary quantity: an Amount numeric property and a Currency code that can be serialized either as a string (the default or providing CurrencyStyle.Alphabetic to the converter constructor) or as a number (providing CurrencyStyle.Numeric to the converter constructor).

Property casing must be configured outside this converter, for example, using a different implementation of DefaultContractResolver.

{"Amount" : 123.4, "Currency" : "XXX"}
{"amount" : 123.4, "currency" : 999}

CurrencyLessMoneyConverter

This converter is a deserializer designed to provide some limited support to legacy integration processes in which a numeric property is included, but no currency is specified in the input, but a default currency (XXX by default) can be provided at the time of instantiating the converter.

ServiceStack

NMoneys ServiceStack Nuget

NuGet version

ServiceStack follows a completely different configuration model than Json.NET. In order to customize how a type needs to be serialized/deserialized a pair of functions is provided to the configurator, via JsConfig<Money>.RawSerializationFx and JsConfig<Money>.RawDeserializationFx.

The functions that can be provided are the ones defined in the static .Serialize() and .Deserialize() methods in the following classes:

  • CanonicalMoneySerializer
  • DefaultMoneySerializer
  • CurrencyLessMoneySerializer

CanonicalMoneySerializer

Provides functions to serialize and deserialize the same input/output as the built-in JSON serialization of the library when using the built-in DataContractJsonSerializer: an Amount numeric property and a Currency object with a three-letter code (by default) IsoCode property.

Property casing must be configured outside this serializer using, for instance, JsConfig.EmitCamelCaseNames.

{"Amount" : 123.4, "Currency" : {"IsoCode" : "XXX"}}

DefaultMoneySerializer

Provides functions to serialize and deserialize the same input/output as a standard serializer would do with a monetary quantity: an Amount numeric property and an alphabetical Currency code.

The currency code can be processed either as a three-letter code (using DefaultMoneySerializer methods) or as a numeric code (using DefaultMoneySerializer.Numeric methods).

Property casing must be configured outside this serializer using, for instance, JsConfig.EmitCamelCaseNames.

{"Amount" : 123.4, "Currency" : "XXX"}
{"amount" : 123.4, "currency" : 999}

CurrencyLessMoneySerializer

Defines a function designed to provide some limited support to legacy integration processes in which a numeric property is included, but no currency is specified in the input, but a default currency (XXX) can be used.

Due to the functional style of configuration, no other default currency can be specified. But source code is easy enough to modify.

RavenDB

NMoneys RavenDB Nuget

NuGet version

RavenDB uses its own "internalized" version of Json.NET under its own namespace. The very same converters (CanonicalMoneyConverter, DefaultMoneyConverter and NumericalMoneyConverter) are included in the package and their usage is exactly the same.

The only difference occurs when configuring the converters, as serialization happens not by invoking a method on JsonConvert. In order to use any of the provided converters, they can be added to the .Converters collection from the JsonSerializer instance configurable via the docStoreInstance.Conventions.CustomizeJsonSerializer delegate. For instance:

var store = new DocumentStore() { /* initialize the store */ };
store.Conventions.CustomizeJsonSerializer = serializer => serializer.Converters.Add(new DefaultMoneyConverter());

MongoDB

NMoneys MongoDB Nuget

NuGet version

Once the package is installed, there are available two custom serializers:

  • CanonicalMoneySerializer
  • DefaultMoneySerializer

In order to use a custom serializer, the serialization components of MongoDB need to be configured as per MongoDB configuration instructions:

Default BSON serialization chooses to represent decimals as strings, instead of numbers. In order to maintain homogeneity with other platforms, a numeric representation has been chosen for amounts. If that choice causes errors due to the lack of accuracy of double, feel free to change the code of the serializers or let us know so that we can program hooks to control such representation.

CanonicalMoneySerializer

This serializer processes the same input/output as the built-in JSON serialization of the library when using the built-in DataContractJsonSerializer: an Amount numeric property and a Currency object with a three-letter code (by default) IsoCode property.

The Amount property is stored using the decimal BSON Type as per the recommendation in the "Model monetary data" pattern.

Property casing must be configured outside this serializer, for example, using a convention such as CamelCaseElementNameConvention.

The currency code enumeration is always represented as a string, regardless of the configured representation of other enumerations (the default being numeric).

{"Amount" : NumberDecimal("123.4"), "Currency" : {"IsoCode" : "XXX"}}
{"amount" : NumberDecimal("123.4"), "currency" : {"isoCode" : "XXX"}}

DefaultMoneySerializer

This serializer produces a standard representation of a monetary quantity: an Amount numeric property and a Currency code that can be serialized either as a number (the default) or as a string (using, for example, representation of BsonType.String for EnumRepresentationConvention).

The Amount property is stored using the decimal BSON Type as per the recommendation in the "Model monetary data" pattern.

Property casing must be configured outside this serializer, for example, using a convention such as CamelCaseElementNameConvention.

{"Amount" : NumberDecimal("123.4"), "Currency" : "XXX"}
{"amount" : NumberDecimal("123.4"), "currency" : 999}

MongoDB (legacy)

NMoneys MongoDB (legacy) Nuget

NuGet version

Once the package is installed, there are available two custom serializers:

  • CanonicalMoneySerializer
  • DefaultMoneySerializer

In order to use a custom serializer, the serialization components of MongoDB need to be configured as per MongoDB configuration instructions:

Default BSON serialization chooses to represent decimals as strings, instead of numbers. In order to maintain homogeneity with other platforms, a numeric representation has been chosen for amounts. If that choice causes errors due to the lack of accuracy of double, feel free to change the code of the serializers or let us know so that we can program hooks to control such representation.

CanonicalMoneySerializer

This serializer processes the same input/output as the built-in JSON serialization of the library when using the built-in DataContractJsonSerializer: an Amount numeric property and a Currency object with a three-letter code (by default) IsoCode property.

The Amount property is stored using the double BSON Type, making it susceptible to loose data due to lack of precision. For representation purposes that would be ok, but if any arithmetic needs to be done, I would strongly recommend upgrading to a newer version of MongoDB that supports decimal arithmetic.

Property casing must be configured outside this serializer, for example, using a convention such as CamelCaseElementNameConvention.

The currency code enumeration is always represented as a string, regardless of the configured representation of other enumerations (the default being numeric).

{"Amount" : 123.4, "Currency" : {"IsoCode" : "XXX"}}
{"amount" : 123.4, "currency" : {"isoCode" : "XXX"}}

DefaultMoneySerializer

This serializer produces a standard representation of a monetary quantity: an Amount numeric property and a Currency code that can be serialized either as a number (the default) or as a string (using, for example, representation of BsonType.String for EnumRepresentationConvention).

The Amount property is stored using the double BSON Type, making it susceptible to loose data due to lack of precision. For representation purposes that would be ok, but if any arithmetic needs to be done, I would strongly recommend upgrading to a newer version of MongoDB that supports decimal arithmetic.

Property casing must be configured outside this serializer, for example, using a convention such as CamelCaseElementNameConvention.

{"Amount" : 123.4, "Currency" : "XXX"}
{"amount" : 123.4, "currency" : 999}

Entity Framework

NMoneys Entity Framework Nuget

NuGet version

Although not strictly true, one can consider persistence using Entity Framework a sort of serialization. Once the package has been installed, entities that contain monetary quantities can use the type MonetaryQuantity for those properties storing moneys.

Once entities are sorted out, the method .Configure() from MonetaryQuantityCanonicalConfigurator (or the .ConfigureMonetaryQuantity() extension method) can be used to configure the complex type and its canonical storage.

By default, currencies are stored as three-characters-long fixed length strings and amounts stored as the usual numeric(19, 4). If such canonical storage needs to be modified, the source code of the class can be easily changed.