Working with YAML in C# (.NET): Libraries and Practical Examples
YAML (YAML Ain't Markup Language) is a popular data serialization format widely used for configuration files, DevOps (Ansible, Kubernetes, Docker Compose), and data exchange. The .NET ecosystem does not have built-in YAML support, but there are powerful third-party libraries. In this article, we will look at two main ones: YamlDotNet (the most popular) and SharpYaml (a lightweight alternative), and show how to integrate them into C# projects.
1. Why Choose YAML over JSON/XML?
- Human-readable syntax with indentation (no brackets or quotes).
- Support for comments (starting with #).
- Built-in support for complex structures (lists, dictionaries, multi-line strings).
- De facto standard for configurations in containerization and CI/CD.
2. Main Library: YamlDotNet
YamlDotNet is the most mature and maintained library for .NET (including .NET Core, .NET 5+). It provides a full cycle: deserialization (YAML → C# objects) and serialization (objects → YAML).
2.1 Installation via NuGet
dotnet add package YamlDotNetOr via the Visual Studio package manager: Install-Package YamlDotNet.
2.2 Basic Deserialization
Suppose we have a file config.yaml:
# Application settingsapp: name: MyApp version: 1.0.0 debug: false
database: host: localhost port: 5432 credentials: user: admin password: secretLet's create the corresponding C# classes:
public class AppConfig{ public string Name { get; set; } public string Version { get; set; } public bool Debug { get; set; }}
public class DatabaseConfig{ public string Host { get; set; } public int Port { get; set; } public Credentials Credentials { get; set; }}
public class Credentials{ public string User { get; set; } public string Password { get; set; }}
public class RootConfig{ public AppConfig App { get; set; } public DatabaseConfig Database { get; set; }}Now let's parse YAML into objects:
using YamlDotNet.Serialization;using YamlDotNet.Serialization.NamingConventions;
var yamlContent = File.ReadAllText("config.yaml");
var deserializer = new DeserializerBuilder() .WithNamingConvention(UnderscoredNamingConvention.Instance) // for underscores .Build();
var config = deserializer.Deserialize<RootConfig>(yamlContent);
Console.WriteLine($"App: {config.App.Name} v{config.App.Version}");Console.WriteLine($"DB host: {config.Database.Host}:{config.Database.Port}");2.3 Serializing Objects to YAML
var serializer = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .Build();
var config = new RootConfig{ App = new AppConfig { Name = "TestApp", Version = "2.0.0", Debug = true }, Database = new DatabaseConfig { Host = "192.168.1.1", Port = 3306, Credentials = new Credentials { User = "root", Password = "qwerty" } }};
string yamlOutput = serializer.Serialize(config);Console.WriteLine(yamlOutput);2.4 Working with Dynamic Data
If the YAML structure is unknown in advance, use Dictionary<object, object>:
var deserializer = new DeserializerBuilder() .Build();
var result = deserializer.Deserialize<Dictionary<object, object>>(yamlContent);// Recursive dictionary traversalPrintYaml(result, 0);
void PrintYaml(Dictionary<object, object> dict, int indent){ foreach (var kvp in dict) { Console.WriteLine($"{new string(' ', indent * 2)}{kvp.Key}: {kvp.Value}"); Also in library
Kotlin Task Scheduler: kotlinx.coroutines and Libraries for Background Tasks
gRPC for Swift (iOS/macOS): Libraries, Setup, and Code Examples
CLI framework for Rust: Clap — a powerful and convenient tool for creating console applications
range-v3 for C++: Complete Guide with Examples