Lesson 12 of 13
Files, JSON & HTTP
Learn to read and write files, convert objects to and from , and call an using .NET's built-in tools.
using System.IO;
using System.Text;
// Whole-file helpers
await File.WriteAllTextAsync("notes.txt", "first line\nsecond line\n");
string content = await File.ReadAllTextAsync("notes.txt");
string[] lines = await File.ReadAllLinesAsync("notes.txt");
await File.AppendAllTextAsync("notes.txt", "third line\n");
// Streaming a large file — constant memory
await foreach (string line in File.ReadLinesAsync("huge.log"))
{
if (line.Contains("ERROR")) Console.WriteLine(line);
}
// Writers and using declarations (disposed at end of scope)
using var writer = new StreamWriter("out.csv", append: false, Encoding.UTF8);
await writer.WriteLineAsync("id,name");
await writer.WriteLineAsync("1,Ada");
// Paths — never concatenate with "/" by hand
string path = Path.Combine(AppContext.BaseDirectory, "data", "report.csv");
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
Console.WriteLine(Path.GetExtension(path)); // .csv
Console.WriteLine(File.Exists(path));
foreach (var file in Directory.EnumerateFiles("data", "*.csv", SearchOption.AllDirectories))
Console.WriteLine(file);using System.Text.Json;
using System.Text.Json.Serialization;
public record Todo(int Id, string Title, bool Completed)
{
[JsonPropertyName("due_date")]
public DateOnly? DueDate { get; init; }
[JsonIgnore]
public string Internal { get; init; } = "";
}
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
var todo = new Todo(1, "Write docs", false) { DueDate = new DateOnly(2026, 9, 1) };
string json = JsonSerializer.Serialize(todo, options);
Console.WriteLine(json);
Todo? back = JsonSerializer.Deserialize<Todo>(json, options);
// Straight to and from a file, without building the whole string
await using (var fs = File.Create("todo.json"))
await JsonSerializer.SerializeAsync(fs, todo, options);
await using (var fs = File.OpenRead("todo.json"))
{
var loaded = await JsonSerializer.DeserializeAsync<Todo>(fs, options);
Console.WriteLine(loaded?.Title);
}using System.Net.Http;
using System.Net.Http.Json;
// Create ONE HttpClient and reuse it. A new one per request exhausts sockets.
static readonly HttpClient Http = new()
{
BaseAddress = new Uri("https://api.example.com/"),
Timeout = TimeSpan.FromSeconds(10),
};
// GET and deserialize in one call
var todos = await Http.GetFromJsonAsync<List<Todo>>("todos");
// POST an object as JSON
var response = await Http.PostAsJsonAsync("todos", new Todo(0, "New task", false));
response.EnsureSuccessStatusCode(); // throws on 4xx/5xx
var created = await response.Content.ReadFromJsonAsync<Todo>();
// Full control plus cancellation
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using var request = new HttpRequestMessage(HttpMethod.Get, "todos/1");
request.Headers.Add("Authorization", "Bearer token123");
try
{
using var res = await Http.SendAsync(request, cts.Token);
Console.WriteLine((int)res.StatusCode);
Console.WriteLine(await res.Content.ReadAsStringAsync(cts.Token));
}
catch (TaskCanceledException)
{
Console.WriteLine("request timed out");
}Finished reading?Mark it done to track your progress.
Tip: use the ← and → keys to move between lessons.