Skip to content

Serializing to JSON, XML and more

Andreas Gullberg Larsen edited this page Nov 16, 2021 · 7 revisions

Serialization

The currently supported methods of serialization:

UnitsNet.Serialization.JsonNet with Json.NET (Newtonsoft)

Example

var jsonSerializerSettings = new JsonSerializerSettings {Formatting = Formatting.Indented};
jsonSerializerSettings.Converters.Add(new UnitsNetIQuantityJsonConverter());

string json = JsonConvert.SerializeObject(new { Name = "Raiden", Weight = Mass.FromKilograms(90) }, jsonSerializerSettings);

object obj = JsonConvert.DeserializeObject(json);

JSON output:

{
  "Name": "Raiden",
  "Weight": {
    "Unit": "MassUnit.Kilogram",
    "Value": 90.0
  }
}

Serializing IComparable

If you need to support deserializing into properties/fields of type IComparable instead of type IQuantity, then you can add

jsonSerializerSettings.Converters.Add(new UnitsNetIComparableJsonConverter());

DataContractSerializer for XML

All quantities and the IQuantity interface have [DataContract] annotations and can be serialized by the built-in XML DataContractSerializer.

<Power xmlns="http://schemas.datacontract.org/2004/07/UnitsNet"
       xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Value>1.20</Value>
    <Unit>Milliwatt</Unit>
</Power>

Serializing IQuantity with additional type information:

[DataContract]
[KnownType(typeof(Mass))]
[KnownType(typeof(Information))]
public class Foo
{
    [DataMember]
    public IQuantity Quantity { get; set; }
}

// Serialized object
new Foo { Quantity = new Information(1.20m, InformationUnit.Exabyte) };
<Foo xmlns="http://schemas.datacontract.org/2004/07/UnitsNet.Tests.Serialization"
                     xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Quantity i:type="a:Information" xmlns:a="http://schemas.datacontract.org/2004/07/UnitsNet">
        <a:Value>1.20</a:Value>
        <a:Unit>Exabyte</a:Unit>
    </Quantity>
</Foo>

DataContractJsonSerializer for JSON (not recommended)

For JSON, we recommend UnitsNet.Serialization.JsonNet with Json.NET (Newtonsoft) instead.

DataContractJsonSerializer is not recommended, because the enum value is serialized as integer and this value is not stable.

Schema:

{
  "__type": "Information:#UnitsNet",
  "Value": 1.20,
  "Unit": 4
}

System.Text.Json (not yet implemented)

See #905, #966.

Protobuf and other [DataContract] compatible serializers

TODO Test and document here.

Backwards compatibility

We strive to maintain backwards compatibility of round-trip serialization within a major version. However, the quantities and units themselves are inherently not stable:

  • The base unit of quantities has changed several times in the history, e.g. Kilogram -> Gram.
  • The unit enum value is not stable due to code generator sorting units alphabetically.

This is why the full unit name is serialized in Json.NET, so we can avoid ambiguity and be robust to any internal changes of the quantities and units.