Holger Stehle

Softwareentwicklung und -architektur

« GET- und POST-Anfragen senden

Für viele APIs – aber auch so manchen Test – ist es hilfreich, GET- und POST-Anfragen per HTTP senden zu können. Selbstverständlich ist das auch per C# sehr einfach möglich, wobei je nach gewünschtem Grad der Kontrollierbarkeit der Anfragen verschiedene Abstrahierungen zur Verfügung gestellt werden:

Die umfangreichsten Möglichkeiten (und geringen Abstraktiongrad) bietet HttpWebRequest:

// GET per HttpWebRequest
HttpWebRequest webRequest = HttpWebRequest.CreateHttp("…/?key1=val1&key2=val2");

using(HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse()) {
    using(StreamReader streamReader = new(webResponse.GetResponseStream())) {
        string response = streamReader.ReadToEnd();
    }
}

// POST per HttpWebRequest
HttpWebRequest webRequest = HttpWebRequest.CreateHttp("…");

byte[] data = Encoding.UTF8.GetBytes("key1=val1&key2=val2");

webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = data.Length;

using(Stream stream = webRequest.GetRequestStream()) {
    stream.Write(data, 0, data.Length);
}

using(HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse()) {
    using(StreamReader streamReader = new(webResponse.GetResponseStream())) {
        string response = streamReader.ReadToEnd();
    }
}

Deutlich kompakter lassen sich entsprechende Anfragen per WebClient formulieren:

// GET per WebClient
using(WebClient webClient = new()) {
    string response = webClient.DownloadString("…/?key1=val1&key2=val2");
}

// POST per WebClient
using(WebClient webClient = new()) {
    string response = Encoding.UTF8.GetString(webClient.UploadValues("…", new NameValueCollection() {
        {"key1", "val1"},
        {"key2", "val2"}
    }));
}

Die aktuellste Möglichkeit mit Fokus auf asynchrone Vorgänge stellt HttpClient dar:

// GET per HttpClient
using(HttpClient client = new()) {
    string response = await client.GetStringAsync("…/?key1=val1&key2=val2");
}

// POST per HttpClient
using(HttpClient httpClient = new()) {
    HttpResponseMessage responseMessage = await httpClient.PostAsync("…",
        new FormUrlEncodedContent(new Dictionary<string, string>() {
            {"key1", "val1"},
            {"key2", "val2"}
        })
    );

    string response = await responseMessage.Content.ReadAsStringAsync();
}

Grundsätzlich bestünde auch noch die Möglichkeit, auf TCP-Ebene unter Anwendung des HTTP-Protokolls vorzugehen. Abschließend sei noch erwähnt, dass diese Möglichkeiten nicht für fragliche Aktionen genutzt werden sollte – dazu gehört im Übrigen auch schlicht unnötiger Traffic.