---
title: "Serialize a C# object to YAML"
url: https://recursiveai.org/oneyaml/csharp/cookbook/write-yaml/
description: "Serialize a C# object to a YAML file with OneYaml’s YamlSerializer.Serialize: naming policies, skipping nulls, lists and dictionaries, and the file read back. A complete Program.cs with its real output."
version: "1.2.1"
---

# Serialize a C# object to YAML

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.

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

Put this in `Program.cs` and run `dotnet run`:

```csharp
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](https://recursiveai.org/oneyaml/csharp/cookbook/edit-yaml-keep-comments/).
- **Reflection by default.** For trimmed or native AOT apps, pass generated metadata: [YAML in a native AOT app](https://recursiveai.org/oneyaml/csharp/cookbook/native-aot/).

To read the file into the class: [deserialize YAML into a class](https://recursiveai.org/oneyaml/csharp/cookbook/parse-yaml-into-classes/).
