Recursive AI

Serialize a C# object to YAML

All oneyaml C# recipes

Call YamlSerializer.Serialize(value) and write the string to a file. Properties come out in declaration order, in block style, named in camel case by default.

Terminal
dotnet new console -o WriteYaml && cd WriteYaml
dotnet add package OneYaml --version 1.2.1

Put this in Program.cs and run dotnet run:

C#
using OneYaml;
 
var svc = new Service
{
    Name = "web",
    Image = "nginx:1.27",
    Replicas = 2,
    Ports = [80, 443],
    Env = new() { ["LOG_LEVEL"] = "info", ["PORT"] = "8080" },
    Note = "no",
};
 
var options = new YamlSerializerOptions
{
    DefaultIgnoreCondition = YamlIgnoreCondition.WhenWritingNull,
};
string yaml = YamlSerializer.Serialize(svc, options);
File.WriteAllText("service.yaml", yaml);
Console.Write(yaml);
 
// Read it back.
var back = YamlSerializer.Deserialize<Service>(File.ReadAllText("service.yaml"))!;
Console.WriteLine($"read back: {back.Name} x{back.Replicas}, note \"{back.Note}\"");
 
class Service
{
    public string Name { get; set; } = "";
    public string Image { get; set; } = "";
    public int Replicas { get; set; }
    public List<int> Ports { get; set; } = [];
    public Dictionary<string, string> Env { get; set; } = [];
    public string? Command { get; set; }
    public string Note { get; set; } = "";
}
Text
name: web
image: nginx:1.27
replicas: 2
ports:
  - 80
  - 443
env:
  LOG_LEVEL: info
  PORT: '8080'
note: 'no'
read back: web x2, note "no"

Command is null and WhenWritingNull leaves it out. Strings that some reader could take for another type are quoted, so the file means what the object held for every parser: '8080', and 'no', which unquoted a YAML 1.1 parser would read as false. Serialize also writes to a Stream or TextWriter, and PropertyNamingPolicy sets another naming style.

Limits

  • No comments. An object has nowhere to keep them. To change a file people maintain by hand and keep its comments, edit it as a YamlDocument: edit YAML and keep its comments.
  • Reflection by default. For trimmed or native AOT apps, pass generated metadata: YAML in a native AOT app.

To read the file into the class: deserialize YAML into a class.