Vogen Help

Serializing to and from JSON

In this tutorial, we'll see how to serialize and deserialize value objects.

Vogen can automatically generate the code required for this. It supports System.Text.Json (STJ), Newtonsoft.Json (NSJ), and ServiceStack.Text

First, let's see what we get with no conversion generated. In a C# project that references Vogen, create the following type:

[ValueObject<float>(conversions: Conversions.None)] public readonly partial struct Celsius { }

Now, serialize an instance of Celsius to a JSON string using Newtonsoft.Json:

public record Weather( string Summary, Celcius TemperatureTodayInCelsius); var weather = new() { Summary = "Sunny and hot", TemperatureTodayInCelsius = Celsius.From(30) }; Console.WriteLine(JsonSerializer.Serialize(weather));

You'll see:

{"Summary":"Sunny and hot","TemperatureTodayInCelsius":{"Value":30}}

Note that the serializer has written the temperature as a composite object (Value:30).

This isn't ideal as you probably want the primitive value written; also, Vogen won't be able to deserialize that composite value back into a value object.

To get just the primitive value written, change Celcius to this and rerun.

[ValueObject<float>(Conversions.SystemTextJson)] public readonly partial struct Celsius { }

This outputs:

{ Summary = Sunny and hot, TemperatureTodayInCelsius = 30 }

As well as treating the value object as a primitive, it also allows it to be deserialized back into a value object. Not that the default configuration says to generate System.Text.Json converters, so you could remove the Conversions parameter altogether.

Serializing with source generation

System.Text.Json also has source generators that build up the required mappers during build time. Vogen is compatible with this. Let's change the example above to use STJ source generation.

Add the following type:

[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Weather))] internal partial class JsonSourceGenerationContext : JsonSerializerContext { }

Now, when serializing, you have to tell STJ to use the converter factory that is generated by Vogen:

var options = new JsonSerializerOptions { WriteIndented = true, Converters = { new VogenTypesFactory() } }; var ctx = new JsonSourceGenerationContext(options); var json = JsonSerializer.Serialize(weather, ctx.Weather); Weather w2 = JsonSerializer.Deserialize(json, ctx.Weather)!;

The STJ converter factory is generated automatically if referencing the new STJ types in the System.Text.Json.Serialization namespace.

You can turn this off via the SystemTextJsonConverterFactoryGeneration flag in config (either globally, or per value object)

Summary

In this tutorial, we've seen how JSON is serialized if no conversions are specified, and then we've seen the difference that specifying the conversion makes.

Last modified: 16 September 2024