Einleitung: Warum ein korrekter HTTP-Client in C# wichtig ist
In der modernen Entwicklung mit C# (.NET) ist die Arbeit mit HTTP-Anfragen eine grundlegende Notwendigkeit. Ob es um die Anbindung an eine REST-API, das Herunterladen von Daten von einem Webserver oder die Integration mit Cloud-Diensten geht – ohne einen zuverlässigen HTTP-Client kommt man nicht aus. Viele Entwickler, insbesondere Anfänger, machen jedoch typische Fehler: falsches Verbindungsmanagement, Ignorieren von Timeouts oder ineffiziente Verarbeitung von Antworten. In diesem Artikel werden wir die Erstellung eines HTTP-Clients in C# von den Grundlagen bis zu fortgeschrittenen Techniken behandeln.
Wir betrachten die Klasse HttpClient – das wichtigste Werkzeug für die Arbeit mit HTTP in .NET – sowie alternative Ansätze. Sie erfahren, wie Sie GET- und POST-Anfragen korrekt senden, JSON verarbeiten, Header verwalten und häufige Leistungsprobleme vermeiden.
Grundlagen: Erstellen und Konfigurieren von HttpClient
Korrekte Initialisierung von HttpClient
Die Klasse HttpClient ist für die Wiederverwendung konzipiert. Für jede Anfrage eine neue Instanz zu erstellen, ist ein Anti-Pattern, das zur Erschöpfung von Sockets führen kann. Verwenden Sie stattdessen eine einzige Instanz für die gesamte Anwendung oder Dependency Injection (DI) über IHttpClientFactory.
// Falsch: Erstellung für jede Anfragepublic async Task<string> BadRequest(string url){ using (var client = new HttpClient()) { return await client.GetStringAsync(url); }}
// Richtig: Statische Instanzpublic static readonly HttpClient SharedClient = new HttpClient();
// Oder über IHttpClientFactory (empfohlen für ASP.NET Core)services.AddHttpClient("MyClient", client =>{ client.BaseAddress = new Uri("https://api.example.com"); client.DefaultRequestHeaders.Add("Accept", "application/json");});Konfiguration von Timeouts und Basisadresse
Timeouts schützen die Anwendung vor Hängern, wenn der Server nicht erreichbar ist. HttpClient hat einen eigenen Timeout, der jedoch überschrieben werden kann.
HttpClient client = new HttpClient{ BaseAddress = new Uri("https://jsonplaceholder.typicode.com"), Timeout = TimeSpan.FromSeconds(10) // 10 Sekunden für die gesamte Anfrage};Es ist auch sinnvoll, MaxResponseContentBufferSize festzulegen, um die Größe der empfangenen Daten zu begrenzen.
Senden von Anfragen: GET, POST, PUT und DELETE
GET-Anfrage: Daten abrufen
Der einfachste Weg, Daten abzurufen, ist GetStringAsync oder GetAsync mit manueller Verarbeitung.
public async Task<string> GetUsersAsync(){ HttpResponseMessage response = await SharedClient.GetAsync("/users"); response.EnsureSuccessStatusCode(); // wirft eine Ausnahme bei Fehlern return await response.Content.ReadAsStringAsync();}
// Oder noch einfacher:string json = await SharedClient.GetStringAsync("/users");POST-Anfrage: Daten senden
Verwenden Sie zum Senden von JSON PostAsJsonAsync (erfordert das Paket System.Net.Http.Json).
var newUser = new { name = "Ivan", email = "ivan@example.com" };HttpResponseMessage response = await SharedClient.PostAsJsonAsync("/users", newUser);if (response.IsSuccessStatusCode){ var createdUser = await response.Content.ReadFromJsonAsync<User>();}Verwenden Sie zum Senden eines Formulars FormUrlEncodedContent.
var formData = new Dictionary<string, string>{ { "username", "admin" }, { "password", "secret" }};var content = new FormUrlEncodedContent(formData);HttpResponseMessage response = await SharedClient.PostAsync("/login", content);PUT- und DELETE-Anfragen
Aktualisieren und Löschen erfolgen analog:
// PUTvar updateData = new { id = 1, name = "Aktualisierter Name" };HttpResponseMessage putR