JSON serialisation
Turn objects into JSON text and back with System.Text.Json: options, attributes, lists, and handling bad input.
System.Text.Json.
using System.Text.Json; public record Beam(string Mark, string Profile, double LengthM); var beam = new Beam("B12", "IPE300", 6.5);string json = JsonSerializer.Serialize(beam);Console.WriteLine(json); Beam? back = JsonSerializer.Deserialize<Beam>(json);Console.WriteLine(back);{"Mark":"B12","Profile":"IPE300","LengthM":6.5}
Beam { Mark = B12, Profile = IPE300, LengthM = 6.5 }JSON in 30 seconds
| JSON | C# |
|---|---|
{ "name": value, … } object | |
[ … ] array | List<T> or T[] |
"text" | string |
12.5 | int, double, decimal |
true / false | bool |
null | null |
Options
var options = new JsonSerializerOptions{ WriteIndented = true, // human-readable PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // Mark → mark PropertyNameCaseInsensitive = true // when reading}; var members = new List<Beam> { new("B1", "IPE200", 4.0), new("B2", "IPE300", 6.0) };string json = JsonSerializer.Serialize(members, options);Console.WriteLine(json);[
{
"mark": "B1",
"profile": "IPE200",
"lengthM": 4
},
{
"mark": "B2",
"profile": "IPE300",
"lengthM": 6
}
]Attributes for control
using System.Text.Json.Serialization; public class ProjectSettings{ [JsonPropertyName("project_name")] public string Name { get; set; } = ""; public int Units { get; set; } [JsonIgnore] public string TempPath { get; set; } = ""; // never written}Saving and loading a file
static void Save<T>(string path, T data) => File.WriteAllText(path, JsonSerializer.Serialize(data, Options)); static T? Load<T>(string path) => File.Exists(path) ? JsonSerializer.Deserialize<T>(File.ReadAllText(path), Options) : default; Save("members.json", members);var loaded = Load<List<Beam>>("members.json") ?? new List<Beam>();Console.WriteLine(loaded.Count);2
Bad input
try{ var b = JsonSerializer.Deserialize<Beam>("""{ "Mark": "B1", "LengthM": "long" }""");}catch (JsonException ex){ Console.WriteLine(ex.Message);}The JSON value could not be converted to System.Double. Path: $.LengthM | LineNumber: 0 | BytePositionInLine: 33.
JsonException, and check that required values are present after deserialising.
AppSettings with Theme (string, default "dark"), RecentFiles (List<string>) and AutoSaveMinutes (int, default 5). Load it from "settings.json" if it exists, otherwise create defaults; add "tower.ifc" to RecentFiles; save it back indented.
Show the solution
using System.Text.Json; var options = new JsonSerializerOptions { WriteIndented = true };const string path = "settings.json"; AppSettings settings = File.Exists(path) ? JsonSerializer.Deserialize<AppSettings>(File.ReadAllText(path), options) ?? new() : new(); settings.RecentFiles.Add("tower.ifc");File.WriteAllText(path, JsonSerializer.Serialize(settings, options));Console.WriteLine(File.ReadAllText(path)); public class AppSettings{ public string Theme { get; set; } = "dark"; public List<string> RecentFiles { get; set; } = new(); public int AutoSaveMinutes { get; set; } = 5;}{
"Theme": "dark",
"RecentFiles": [
"tower.ifc"
],
"AutoSaveMinutes": 5
}Remember
JsonSerializer.Serializemakes JSON;Deserialize<T>reads it back.Options control indentation, naming (camelCase) and case-insensitive reading. Use [JsonPropertyName]and[JsonIgnore]for per-property control.Reuse one options object; catch JsonExceptionfor untrusted input.