Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Lernprogramm wird eine App erstellt, die HTTP-Anforderungen an einen REST-Dienst auf GitHub ausgibt. Die App liest Informationen im JSON-Format und konvertiert den JSON-Code in C#-Objekte. Das Konvertieren von JSON in C#-Objekte wird als Deserialisierung bezeichnet.
Das Lernprogramm zeigt, wie Sie:
- HTTP-Anforderungen senden.
- Json-Antworten deserialisieren.
- Konfigurieren Sie die Deserialisierung mit Attributen.
Wenn Sie es lieber zusammen mit dem endgültigen Beispiel für dieses Lernprogramm befolgen möchten, können Sie es herunterladen. Anweisungen zum Herunterladen finden Sie unter Beispiele und Lernprogramme.
Voraussetzungen
- Das neueste .NET SDK
- Visual Studio Code-Editor
- Das C# DevKit
Erstellen der Client-App
Öffnen Sie eine Eingabeaufforderung, und erstellen Sie ein neues Verzeichnis für Ihre App. Stellen Sie sicher, dass das aktuelle Verzeichnis ist.
Geben Sie den folgenden Befehl in ein Konsolenfenster ein:
dotnet new console --name WebAPIClientMit diesem Befehl werden die Startdateien für eine einfache "Hello World"-App erstellt. Der Projektname lautet "WebAPIClient".
Navigieren Sie zum Verzeichnis "WebAPIClient", und führen Sie die App aus.
cd WebAPIClientdotnet rundotnet runwird automatisch ausgeführtdotnet restore, um abhängigkeiten wiederherzustellen, die die App benötigt. Sie wird auch bei Bedarf ausgeführtdotnet build. Die App-Ausgabe"Hello, World!"sollte angezeigt werden. Drücken Sie in Ihrem Terminal STRG+C , um die App zu beenden.
Übermitteln von HTTP-Anforderungen
Diese App ruft die GitHub-API auf, um Informationen zu den Projekten unter dem .NET Foundation-Dach abzurufen. Der Endpunkt ist https://api.github.com/orgs/dotnet/repos. Um Informationen abzurufen, wird eine HTTP GET-Anforderung gestellt. Browser stellen auch HTTP GET-Anforderungen, sodass Sie diese URL in ihre Browseradressleiste einfügen können, um zu sehen, welche Informationen Sie empfangen und verarbeiten werden.
Verwenden Sie die HttpClient Klasse, um HTTP-Anforderungen zu stellen. HttpClient unterstützt nur asynchrone Methoden für die langfristig ausgeführten APIs. Die folgenden Schritte erstellen also eine asynchrone Methode und rufen sie aus der Main-Methode auf.
Öffnen Sie die
Program.csDatei im Projektverzeichnis, und ersetzen Sie deren Inhalt durch Folgendes:await ProcessRepositoriesAsync(); static async Task ProcessRepositoriesAsync(HttpClient client) { }Dieser Code:
- Ersetzt die
Console.WriteLineAnweisung durch einen Aufruf, derProcessRepositoriesAsyncdasawaitSchlüsselwort verwendet. - Definiert eine leere
ProcessRepositoriesAsyncMethode.
- Ersetzt die
Verwenden Sie in der
ProgramKlasse eine HttpClient Zum Behandeln von Anforderungen und Antworten, indem Sie den Inhalt durch den folgenden C# ersetzen.using System.Net.Http.Headers; using HttpClient client = new(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); await ProcessRepositoriesAsync(client); static async Task ProcessRepositoriesAsync(HttpClient client) { }Dieser Code:
- Richtet HTTP-Header für alle Anforderungen ein:
- Ein
AcceptHeader zum Akzeptieren von JSON-Antworten - Eine
User-AgentKopfzeile. Diese Header werden vom GitHub-Servercode überprüft und sind erforderlich, um Informationen von GitHub abzurufen.
- Ein
- Richtet HTTP-Header für alle Anforderungen ein:
Rufen Sie in der
ProcessRepositoriesAsyncMethode den GitHub-Endpunkt auf, der eine Liste aller Repositorys unter der .NET Foundation-Organisation zurückgibt:static async Task ProcessRepositoriesAsync(HttpClient client) { var json = await client.GetStringAsync( "https://api.github.com/orgs/dotnet/repos"); Console.Write(json); }Dieser Code:
- Erwartet die von der aufrufenden HttpClient.GetStringAsync(String) Methode zurückgegebene Aufgabe. Diese Methode sendet eine HTTP GET-Anforderung an den angegebenen URI. Der Textkörper der Antwort wird als ein String, das verfügbar ist, wenn die Aufgabe abgeschlossen ist.
- Die Antwortzeichenfolge
jsonwird auf die Konsole gedruckt.
Erstellen Sie die App, und führen Sie sie aus.
dotnet runEs gibt keine Buildwarnung, da die
ProcessRepositoriesAsyncjetzt einenawaitOperator enthält. Die Ausgabe ist eine lange Anzeige von JSON-Text.
Deserialisieren des JSON-Ergebnisses
Die folgenden Schritte vereinfachen den Ansatz zum Abrufen der Daten und deren Verarbeitung. Sie verwenden die GetFromJsonAsync Erweiterungsmethode, die Teil des 📦 Pakets "System.Net.Http.Json NuGet" ist, um die JSON-Ergebnisse in Objekte abzurufen und deserialisieren.
Erstellen Sie eine Datei mit dem Namen Repository.cs , und fügen Sie den folgenden Code hinzu:
public record class Repository(string Name);Der vorangehende Code definiert eine Klasse, die das JSON-Objekt darstellt, das von der GitHub-API zurückgegeben wird. Sie verwenden diese Klasse, um eine Liste der Repositorynamen anzuzeigen.
Der JSON-Code für ein Repositoryobjekt enthält Dutzende von Eigenschaften, aber nur die
NameEigenschaft wird deserialisiert. Der Serialisierer ignoriert automatisch JSON-Eigenschaften, für die keine Übereinstimmung in der Zielklasse vorhanden ist. Dieses Feature erleichtert das Erstellen von Typen, die nur mit einer Teilmenge von Feldern in einem großen JSON-Paket funktionieren.Obwohl die Methode, die
GetFromJsonAsyncSie im nächsten Punkt verwenden, die Groß-/Kleinschreibung nicht beachtet, wenn es um Eigenschaftsnamen geht, besteht die C#-Konvention darin, den ersten Buchstaben von Eigenschaftsnamen groß zu schreiben.Verwenden Sie die HttpClientJsonExtensions.GetFromJsonAsync Methode, um JSON in C#-Objekte abzurufen und zu konvertieren. Ersetzen Sie den Aufruf GetStringAsync(String) in der
ProcessRepositoriesAsyncMethode durch die folgenden Zeilen:var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos");Der aktualisierte Code ersetzt GetStringAsync(String) durch HttpClientJsonExtensions.GetFromJsonAsync.
Das erste Argument für die
GetFromJsonAsyncMethode ist einawaitAusdruck.awaitAusdrücke können fast überall im Code angezeigt werden, obwohl Sie sie bis jetzt nur als Teil einer Zuordnungsanweisung gesehen haben. Der nächste Parameter ist optional und muss nicht angegeben werden,requestUriwenn er beim Erstellen desclientObjekts bereits angegeben wurde. Sie haben dasclientObjekt nicht mit dem URI zum Senden der Anforderung bereitgestellt, sodass Sie den URI jetzt angegeben haben. Der letzte optionale Parameter, derCancellationTokenim Codeausschnitt weggelassen wird.Die
GetFromJsonAsyncMethode ist generisch, was bedeutet, dass Sie Typargumente für die Art von Objekten angeben, die aus dem abgerufenen JSON-Text erstellt werden sollen. In diesem Beispiel wird eine Deserialisierung für einList<Repository>anderes generisches Objekt (ein anderes generisches Objekt) ausgeführt System.Collections.Generic.List<T>. DieList<T>Klasse speichert eine Auflistung von Objekten. Das Typargument deklariert den Typ der objekte, die in derList<T>. Das Typargument ist IhrRepositoryDatensatz, da der JSON-Text eine Auflistung von Repositoryobjekten darstellt.Fügen Sie Code hinzu, um den Namen der einzelnen Repositorys anzuzeigen. Ersetzen Sie die Zeilen, die gelesen werden:
Console.Write(json);mit folgendem Code:
foreach (var repo in repositories ?? Enumerable.Empty<Repository>()) Console.WriteLine(repo.Name);Die folgenden
usingRichtlinien sollten am Anfang der Datei vorhanden sein:using System.Net.Http.Headers; using System.Net.Http.Json;Führen Sie die App aus.
dotnet runDie Ausgabe ist eine Liste der Namen der Repositorys, die Teil von .NET Foundation sind.
Umgestalten des Codes
Die ProcessRepositoriesAsync Methode kann die asynchrone Arbeit ausführen und eine Sammlung der Repositorys zurückgeben. Ändern Sie diese Methode, um sie zurückzugeben Task<List<Repository>>, und verschieben Sie den Code, der in die Konsole in der Nähe des Aufrufers schreibt.
Ändern Sie die Signatur,
ProcessRepositoriesAsyncum eine Aufgabe zurückzugeben, deren Ergebnis eine Liste vonRepositoryObjekten ist:static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)Geben Sie die Repositorys nach der Verarbeitung der JSON-Antwort zurück:
var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new();Der Compiler generiert das
Task<T>Objekt für den Rückgabewert, da Sie diese Methode alsasyncgekennzeichnet haben.Ändern Sie die Program.cs Datei, und ersetzen Sie den Aufruf
ProcessRepositoriesAsyncdurch Folgendes, um die Ergebnisse zu erfassen, und schreiben Sie jeden Repositorynamen in die Konsole.var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) Console.WriteLine(repo.Name);Führen Sie die App aus.
Die Ausgabe ist identisch.
Deserialisieren weiterer Eigenschaften
In den folgenden Schritten erweitern wir den Code, um weitere Eigenschaften aus der JSON-Nutzlast zu verarbeiten, die von der GitHub-API zurückgegeben wird. Wahrscheinlich müssen Sie nicht jede Eigenschaft verarbeiten, aber das Hinzufügen einiger Eigenschaften veranschaulicht zusätzliche C#-Features.
Ersetzen Sie den Inhalt der
RepositoryKlasse durch die folgenderecordDefinition. Stellen Sie sicher, dass Sie denSystem.Text.Json.SerializationNamespace importieren und das[JsonPropertyName]Attribut anwenden, um JSON-Felder explizit C#-Eigenschaften zuzuordnen.using System.Text.Json.Serialization; public record class Repository( string Name, string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, Uri Homepage, int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc );Die Und Uri Typen
intverfügen über integrierte Funktionen zum Konvertieren in und aus der Zeichenfolgendarstellung. Für die Deserialisierung von JSON-Zeichenfolgenformaten an diese Zieltypen ist kein zusätzlicher Code erforderlich. Wenn das JSON-Paket Daten enthält, die nicht in einen Zieltyp konvertiert werden, löst die Serialisierungsaktion eine Ausnahme aus.JSON verwendet
lowercasehäufig odersnake_casefür Eigenschaftsnamen. Felder wiehtml_urlundpushed_atfolgen nicht den C#-PascalCase-Benennungskonventionen. Indem[JsonPropertyName]verwendet wird, wird sichergestellt, dass diese JSON-Schlüssel ordnungsgemäß an ihre entsprechenden C#-Eigenschaften gebunden sind, auch wenn sich ihre Namen in der Groß- und Kleinschreibung unterscheiden oder Unterstriche enthalten. Dieser Ansatz garantiert vorhersehbare und stabile Deserialisierung, während PascalCase-Eigenschaftsnamen in C# zugelassen werden. Darüber hinaus istGetFromJsonAsyncdiecase-insensitiveMethode beim Abgleichen von Eigenschaftsnamen, daher ist keine weitere Konvertierung erforderlich.Aktualisieren Sie die
foreachSchleife in der datei Program.cs so, dass die Eigenschaftswerte angezeigt werden:foreach (var repo in repositories) { Console.WriteLine($"Name: {repo.Name}"); Console.WriteLine($"Homepage: {repo.Homepage}"); Console.WriteLine($"GitHub: {repo.GitHubHomeUrl}"); Console.WriteLine($"Description: {repo.Description}"); Console.WriteLine($"Watchers: {repo.Watchers:#,0}"); Console.WriteLine(); }Führen Sie die App aus.
Die Liste enthält jetzt die zusätzlichen Eigenschaften.
Hinzufügen einer Datumseigenschaft
Das Datum des letzten Pushvorgangs wird in dieser Weise in der JSON-Antwort formatiert:
2016-02-08T21:27:00Z
Dieses Format gilt für koordinierte Weltzeit (UTC), sodass das Ergebnis der Deserialisierung ein DateTime Wert ist, dessen Kind Eigenschaft lautet Utc.
Zum Abrufen eines Datums und einer Uhrzeit, das in Ihrer Zeitzone dargestellt wird, müssen Sie eine benutzerdefinierte Konvertierungsmethode schreiben.
Fügen Sie in Repository.cs eine Eigenschaft für die UTC-Darstellung des Datums und der Uhrzeit und einer readonly-Eigenschaft
LastPushhinzu, die das in lokale Uhrzeit konvertierte Datum zurückgibt, sollte die Datei wie folgt aussehen:using System.Text.Json.Serialization; public record class Repository( string Name, string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, Uri Homepage, int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc ) { public DateTime LastPush => LastPushUtc.ToLocalTime(); }Die
LastPushEigenschaft wird mithilfe eines Ausdruckskörperelements für dengetAccessor definiert. Es gibt keinensetAccessor. Das Weglassen dessetAccessors ist eine Möglichkeit, eine schreibgeschützte Eigenschaft in C# zu definieren. (Ja, Sie können schreibgeschützte Eigenschaften in C# erstellen, aber deren Wert ist begrenzt.)Fügen Sie eine weitere Ausgabeausweisung in Program.cs hinzu: erneut:
Console.WriteLine($"Last push: {repo.LastPush}");Die vollständige App sollte der folgenden Program.cs Datei ähneln:
using System.Net.Http.Headers; using System.Net.Http.Json; using HttpClient client = new(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) { Console.WriteLine($"Name: {repo.Name}"); Console.WriteLine($"Homepage: {repo.Homepage}"); Console.WriteLine($"GitHub: {repo.GitHubHomeUrl}"); Console.WriteLine($"Description: {repo.Description}"); Console.WriteLine($"Watchers: {repo.Watchers:#,0}"); Console.WriteLine($"{repo.LastPush}"); Console.WriteLine(); } static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client) { var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new List<Repository>(); }Führen Sie die App aus.
Die Ausgabe enthält das Datum und die Uhrzeit des letzten Pushs an jedes Repository.
Nächste Schritte
In diesem Lernprogramm haben Sie eine App erstellt, die Webanforderungen sendet und die Ergebnisse analysiert. Ihre Version der App sollte nun mit dem fertigen Beispiel übereinstimmen.
Erfahren Sie mehr über das Konfigurieren der JSON-Serialisierung in how to serialize and deserialize (marshal and unmarshal) JSON in .NET.