REST-ClientREST client

EinführungIntroduction

In diesem Tutorial lernen Sie verschiedene Features in .NET Core und der Sprache C# kennen.This tutorial teaches you a number of features in .NET Core and the C# language. Es werden die folgenden Themen abgedeckt:You’ll learn:

  • Grundlagen der .NET Core-Befehlszeilenschnittstelle (CLI)The basics of the .NET Core Command Line Interface (CLI).
  • Eine Übersicht über die Features der Sprache C#An overview of C# Language features.
  • Verwalten von Abhängigkeiten mit NuGetManaging dependencies with NuGet
  • HTTP-KommunikationHTTP Communications
  • Verarbeiten von JSON-InformationenProcessing JSON information
  • Verwalten der Konfiguration mit AttributenManaging configuration with Attributes.

Sie erstellen eine Anwendung, die HTTP-Anforderungen an einen REST-Dienst in GitHub ausgibt.You’ll build an application that issues HTTP Requests to a REST service on GitHub. Sie lesen Informationen im JSON-Format ein und konvertieren das JSON-Paket in C#-Objekte.You'll read information in JSON format, and convert that JSON packet into C# objects. Abschließend lernen Sie die Arbeit mit C#-Objekten kennen.Finally, you'll see how to work with C# objects.

In diesem Tutorial werden viele Features abgedeckt.There are a lot of features in this tutorial. Gehen wir sie einzeln an.Let’s build them one by one.

Wenn Sie lieber das letzte Beispiel für dieses Thema befolgen möchten, können Sie es herunterladen.If you prefer to follow along with the final sample for this topic, you can download it. Anweisungen zum Herunterladen finden Sie unter Beispiele und Lernprogramme.For download instructions, see Samples and Tutorials.

Erforderliche KomponentenPrerequisites

Sie müssen Ihren Computer zur Ausführung von .NET Core einrichten.You’ll need to set up your machine to run .NET core. Die Installationsanweisungen finden Sie auf der Seite .NET Core.You can find the installation instructions on the .NET Core page. Sie können diese Anwendung unter Windows, Linux, macOS oder in einem Docker-Container ausführen.You can run this application on Windows, Linux, macOS or in a Docker container. Sie müssen Ihren bevorzugten Code-Editor installieren.You’ll need to install your favorite code editor. In den folgenden Beschreibungen wird Visual Studio Code verwendet. Hierbei handelt es sich um einen plattformübergreifenden Open Source-Editor.The descriptions below use Visual Studio Code, which is an open source, cross platform editor. Sie können jedoch auch ein beliebiges anderes Tool verwenden, mit dem Sie vertraut sind.However, you can use whatever tools you are comfortable with.

Erstellen der AnwendungCreate the Application

Im ersten Schritt wird eine neue Anwendung erstellt.The first step is to create a new application. Öffnen Sie eine Eingabeaufforderung, und erstellen Sie ein neues Verzeichnis für Ihre Anwendung.Open a command prompt and create a new directory for your application. Legen Sie das Verzeichnis als aktuelles Verzeichnis fest.Make that the current directory. Geben Sie an der Eingabeaufforderung den Befehl dotnet new console ein.Type the command dotnet new console at the command prompt. Hierdurch werden die Startdateien für eine einfache „Hello World“-Anwendung erstellt.This creates the starter files for a basic "Hello World" application.

Bevor Sie damit beginnen, Änderungen durchzuführen, gehen wir die Schritte zur Ausführung der einfachen Hello World-Anwendung durch.Before you start making modifications, let’s go through the steps to run the simple Hello World application. Geben Sie nach dem Erstellen der Anwendung dotnet restore (Siehe Hinweis) an der Eingabeaufforderung.After creating the application, type dotnet restore (see note) at the command prompt. Mit diesem Befehl wird der Prozess zur NuGet-Paketwiederherstellung ausgeführt.This command runs the NuGet package restore process. NuGet ist ein .NET-Paket-Manager.NuGet is a .NET package manager. Mit diesem Befehl werden alle fehlenden abhängigen Komponenten für Ihr Projekt heruntergeladen.This command downloads any of the missing dependencies for your project. Da es sich um ein neues Projekt handelt, ist keine der abhängigen Komponenten vorhanden, deshalb wird zunächst das .NET Core-Framework heruntergeladen.As this is a new project, none of the dependencies are in place, so the first run will download the .NET Core framework. Nach diesem ersten Schritt, Sie müssen nur auszuführende dotnet restore (Siehe Hinweis) Wenn Sie neue abhängigen Pakete hinzufügen oder aktualisieren Sie die Versionen eine Ihrer Abhängigkeiten.After this initial step, you will only need to run dotnet restore (see note) when you add new dependent packages, or update the versions of any of your dependencies.

Nach dem Wiederherstellen der Pakete führen Sie dotnet build aus.After restoring packages, you run dotnet build. Hiermit wird das Buildmodul ausgeführt und Ihre Anwendung erstellt.This executes the build engine and creates your application. Abschließend führen Sie dotnet run aus, um Ihre Anwendung zu starten.Finally, you execute dotnet run to run your application.

Hinzufügen von neuen AbhängigkeitenAdding New Dependencies

Eines der wichtigsten Entwurfsziele für .NET Core ist die Minimierung der Größe der .NET Framework-Installation.One of the key design goals for .NET Core is to minimize the size of the .NET framework installation. Das .NET Core-Anwendungsframework enthält nur die am häufigsten verwendeten Elemente der vollständigen .NET Framework-Version.The .NET Core Application framework contains only the most common elements of the .NET full framework. Wenn eine Anwendung zusätzliche Bibliotheken für einige Features benötigt, fügen Sie solcher Abhängigkeiten, in Ihr C#-Projekt (*csproj) Datei.If an application needs additional libraries for some of its features, you add those dependencies into your C# project (*.csproj) file. Beispielweise müssen Sie das System.Runtime.Serialization.Json-Paket hinzufügen, damit Ihre Anwendung JSON-Antworten verarbeiten kann.For our example, you'll need to add the System.Runtime.Serialization.Json package so your application can process JSON responses.

Öffnen Sie Ihre csproj-Projektdatei.Open your csproj project file. Die erste Zeile der Datei sollte so aussehen:The first line of the file should appear as:

<Project Sdk="Microsoft.NET.Sdk">

Fügen Sie direkt nach dieser Zeile Folgendes ein:Add the following immediately after this line:

   <ItemGroup>
      <PackageReference Include="System.Runtime.Serialization.Json" Version="4.3.0" />
   </ItemGroup> 

Die meisten Code-Editoren bieten Codevervollständigung für verschiedene Versionen dieser Bibliotheken.Most code editors will provide completion for different versions of these libraries. Sie werden in der Regel die neueste Version der hinzugefügten Pakete verwenden.You'll usually want to use the latest version of any package that you add. Es ist jedoch wichtig, sicherzustellen, dass die Versionen aller Pakete übereinstimmen und auch der Version des .NET Core-Anwendungsframeworks entsprechen.However, it is important to make sure that the versions of all packages match, and that they also match the version of the .NET Core Application framework.

Nachdem Sie diese Änderungen vorgenommen haben, führen Sie dotnet restore (Siehe Hinweis) erneut, damit das Paket auf Ihrem System installiert ist.After you've made these changes, you should run dotnet restore (see note) again so that the package is installed on your system.

Ausführen von WebanforderungenMaking Web Requests

Jetzt können Sie damit beginnen, Daten aus dem Web abzurufen.Now you're ready to start retrieving data from the web. In dieser Anwendung lesen Sie Informationen aus der GitHub-API ein.In this application, you'll read information from the GitHub API. Beginnen wir damit, Informationen zu den Projekten unterhalb der Kategorie .NET Foundation einzulesen.Let's read information about the projects under the .NET Foundation umbrella. Hierzu senden Sie zunächst eine Anforderung an die GitHub-API, um Informationen zu den Projekten abzurufen.You'll start by making the request to the GitHub API to retrieve information on the projects. Der verwendete Endpunkt lautet https://api.github.com/orgs/dotnet/repos.The endpoint you'll use is: https://api.github.com/orgs/dotnet/repos. Sie möchten alle Informationen zu diesen Projekten abrufen, deshalb verwenden Sie eine HTTP GET-Anforderung.You want to retrieve all the information about these projects, so you'll use an HTTP GET request. Ihr Browser verwendet ebenfalls HTTP GET-Anforderungen, deshalb können Sie diese URL in Ihren Browser einfügen, um zu sehen, welche Informationen abgerufen und verarbeitet werden.Your browser also uses HTTP GET requests, so you can paste that URL into your browser to see what information you'll be receiving and processing.

Sie verwenden die HttpClient -Klasse zum Ausführen der Webanforderungen.You use the HttpClient class to make web requests. Wie alle modernen .NET-APIs unterstützt HttpClient nur asynchrone Methoden für APIs mit langer Ausführungszeit.Like all modern .NET APIs, HttpClient supports only async methods for its long-running APIs. Sie beginnen mit dem Erstellen einer asynchronen Methode.Start by making an async method. Sie vervollständigen die Implementierung, wenn Sie die Funktionalität der Anwendung erstellen.You'll fill in the implementation as you build the functionality of the application. Öffnen Sie zunächst die Datei program.cs in Ihrem Projektverzeichnis, und fügen Sie der Program-Klasse die folgende Methode hinzu:Start by opening the program.cs file in your project directory and adding the following method to the Program class:

private static async Task ProcessRepositories()
{

}

Sie müssen am Anfang Ihrer Main-Methode eine using-Anweisung hinzufügen, damit der C#-Compiler den Task -Typ erkennt:You'll need to add a using statement at the top of your Main method so that the C# compiler recognizes the Task type:

using System.Threading.Tasks;

Wenn Sie zu diesem Zeitpunkt Ihr Projekt erstellen, erhalten Sie eine Warnung für diese Methode, weil sie keine await-Operatoren enthält und synchron ausgeführt wird.If you build your project at this point, you'll get a warning generated for this method, because it does not contain any await operators and will run synchronously. Ignorieren Sie dies für den Moment. Sie fügen await-Operatoren hinzu, wenn Sie die Methode vervollständigen.Ignore that for now; you'll add await operators as you fill in the method.

Als Nächstes benennen Sie den in der namespace-Anweisung definierten Namespace vom Standardwert ConsoleApp in WebAPIClient um.Next, rename the namespace defined in the namespace statement from its default of ConsoleApp to WebAPIClient. Später definieren wir eine repo-Klasse in diesem Namespace.We'll later define a repo class in this namespace.

Aktualisieren Sie jetzt die Main-Methode, um diese Methode aufzurufen.Next, update the Main method to call this method. Die ProcessRepositories-Methode gibt einen Task zurück, und Sie dürfen das Programm nicht beenden, bevor dieser Task abgeschlossen wurde.The ProcessRepositories method returns a Task, and you shouldn't exit the program before that task finishes. Deshalb müssen Sie die Wait -Methode verwenden, um eine Blockierung einzurichten und auf den Abschluss des Tasks zu warten:Therefore, you must use the Wait method to block and wait for the task to finish:

public static void Main(string[] args)
{
    ProcessRepositories().Wait();
}

Sie verfügen jetzt über ein Programm, das keinerlei Vorgänge ausführt, aber asynchron arbeitet.Now, you have a program that does nothing, but does it asynchronously. Kehren wir zur ProcessRepositories-Methode zurück und erstellen eine erste Version der Methode:Let's go back to the ProcessRepositories method and fill in a first version of it:

private static async Task ProcessRepositories()
{
    var client = new HttpClient();
    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 stringTask = client.GetStringAsync("https://api.github.com/orgs/dotnet/repos");

    var msg = await stringTask;
    Console.Write(msg);
}

Damit eine Kompilierung möglich ist, müssen Sie am Anfang der Datei außerdem zwei neue using-Anweisungen hinzufügen:You'll need to also add two new using statements at the top of the file for this to compile:

using System.Net.Http;
using System.Net.Http.Headers;

Diese erste Version führt eine Webanforderung aus, um die Liste aller Repositorys unterhalb der dotnet foundation-Organisation einzulesen.This first version makes a web request to read the list of all repositories under the dotnet foundation organization. (Die GitHub-ID für die .NET Foundation lautet „dotnet“.)(The gitHub ID for the .NET Foundation is 'dotnet'). Zuerst erstellen Sie einen neuen HttpClient.First, you create a new HttpClient. Dieses Objekt verarbeitet die Anforderung und die Antworten.This object handles the request and the responses. In den nächsten Zeilen wird der HttpClient für diese Anforderung eingerichtet.The next few lines set up the HttpClient for this request. Zunächst wird der HttpClient so konfiguriert, dass er die GitHub-JSON-Antworten akzeptiert.First, it is configured to accept the GitHub JSON responses. Das Format ist einfach JSON.This format is simply JSON. In der nächsten Zeile wird ein Benutzer-Agent-Header für alle Anforderungen von diesem Objekt hinzugefügt.The next line adds a User Agent header to all requests from this object. Diese zwei Header werden vom GitHub-Servercode überprüft und sind erforderlich, um Informationen aus GitHub abzurufen.These two headers are checked by the GitHub server code, and are necessary to retrieve information from GitHub.

Nachdem Sie den HttpClient konfiguriert haben, führen Sie eine Webanforderung aus und rufen die Antwort ab.After you've configured the HttpClient, you make a web request and retrieve the response. In dieser ersten Version verwenden Sie die bequeme HttpClient.GetStringAsync(String)-Methode.In this first version, you use the HttpClient.GetStringAsync(String) convenience method. Diese Hilfsmethode startet einen Task zum Ausführen der Webanforderung. Wenn die Anforderung zurückgegeben wird, liest sie den Antwortstream und extrahiert den Inhalt aus dem Stream.This convenience method starts a task that makes the web request, and then when the request returns, it reads the response stream and extracts the content from the stream. Der Antwortkörper wird als String zurückgegeben.The body of the response is returned as a String. Die Zeichenfolge ist verfügbar, wenn der Task abgeschlossen wurde.The string is available when the task completes.

Die letzten zwei Zeilen dieser Methode warten auf den Task und geben dann die Antwort an die Konsole aus.The final two lines of this method await that task, and then print the response to the console. Erstellen Sie die App, und führen Sie sie aus.Build the app, and run it. Die Buildwarnung wird jetzt nicht mehr angezeigt, weil ProcessRepositories jetzt einen await-Operator enthält.The build warning is gone now, because the ProcessRepositories now does contain an await operator. Sie sehen eine umfangreiche Textanzeige im JSON-Format.You'll see a long display of JSON formatted text.

Verarbeiten des JSON-ErgebnissesProcessing the JSON Result

Zu diesem Zeitpunkt haben Sie Code geschrieben, mit dem eine Antwort von einem Webserver abgerufen und der Text angezeigt wird, der in dieser Antwort enthalten ist.At this point, you've written the code to retrieve a response from a web server, and display the text that is contained in that response. Konvertieren wir jetzt diese JSON-Antwort in C#-Objekte.Next, let's convert that JSON response into C# objects.

Das JSON-Serialisierungsprogramm konvertiert JSON-Daten in C#-Objekte.The JSON Serializer converts JSON data into C# Objects. Ihre erste Aufgabe ist es, einen C#-Klassentyp zur Aufnahme der Informationen zu definieren, die Sie aus dieser Antwort verwenden.Your first task is to define a C# class type to contain the information you use from this response. Gehen wir langsam vor und beginnen mit einem einfachen C#-Typ, der den Namen des Repositorys enthält:Let's build this slowly, so start with a simple C# type that contains the name of the repository:

using System;

namespace WebAPIClient
{
    public class repo
    {
        public string name;
    }
}

Platzieren Sie den obigen Code in einer neuen Datei namens „repo.cs“.Put the above code in a new file called 'repo.cs'. Diese Version der Klasse repräsentiert die einfachste Möglichkeit zum Verarbeiten von JSON-Daten.This version of the class represents the simplest path to process JSON data. Der Klassenname und der Membername stimmen mit den im JSON-Paket verwendeten Namen überein, statt den C#-Konventionen zu folgen.The class name and the member name match the names used in the JSON packet, instead of following C# conventions. Sie beheben dies später, indem Sie einige Konfigurationsattribute angeben.You'll fix that by providing some configuration attributes later. Diese Klasse veranschaulicht ein weiteres wichtiges Feature der JSON-Serialisierung und -Deserialisierung: Nicht alle Felder im JSON-Paket sind Teil dieser Klasse.This class demonstrates another important feature of JSON serialization and deserialization: Not all the fields in the JSON packet are part of this class. Das JSON-Serialisierungsprogramm ignoriert Informationen, die nicht im verwendeten Klassentyp enthalten sind.The JSON serializer will ignore information that is not included in the class type being used. Dieses Feature vereinfacht es, Typen zu erstellen, die nur mit einem Teilsatz der Felder im JSON-Paket funktionieren.This feature makes it easier to create types that work with only a subset of the fields in the JSON packet.

Nun, da Sie den Typ erstellt haben, deserialisieren wir ihn.Now that you've created the type, let's deserialize it. Sie müssen ein DataContractJsonSerializer -Objekt erstellen.You'll need to create a DataContractJsonSerializer object. Dieses Objekt muss den CLR-Typ kennen, der für das abgerufene JSON-Paket erwartet wird.This object must know the CLR type expected for the JSON packet it retrieves. Das Paket aus GitHub enthält eine Sequenz aus Repositorys, deshalb ist List<repo> der richtige Typ.The packet from GitHub contains a sequence of repositories, so a List<repo> is the correct type. Fügen Sie Ihrer ProcessRepositories-Methode die folgende Zeile hinzu:Add the following line to your ProcessRepositories method:

var serializer = new DataContractJsonSerializer(typeof(List<repo>));

Sie verwenden jetzt zwei neue Namespaces, deshalb müssen Sie diese auch hinzufügen:You're using two new namespaces, so you'll need to add those as well:

using System.Collections.Generic;
using System.Runtime.Serialization.Json;

Als Nächstes verwenden Sie das Serialisierungsprogramm, um JSON-Daten in C#-Objekte zu konvertieren.Next, you'll use the serializer to convert JSON into C# objects. Ersetzen Sie den Aufruf von GetStringAsync(String) in Ihrer ProcessRepositories Methode mit den folgenden zwei Zeilen:Replace the call to GetStringAsync(String) in your ProcessRepositories method with the following two lines:

var streamTask = client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos");
var repositories = serializer.ReadObject(await streamTask) as List<repo>;

Beachten Sie, die Sie jetzt verwenden GetStreamAsync(String) anstelle von GetStringAsync(String).Notice that you're now using GetStreamAsync(String) instead of GetStringAsync(String). Das Serialisierungsprogramm verwendet anstelle einer Zeichenfolge einen Stream als Quelle.The serializer uses a stream instead of a string as its source. Erläutern wir einige Features von C#, die oben in der zweiten Zeile verwendet werden.Let's explain a couple features of the C# language that are being used in the second line above. Das Argument für ReadObject(Stream) ist ein await Ausdruck.The argument to ReadObject(Stream) is an await expression. Await-Ausdrücke können fast überall in Ihrem Code auftauchen, auch wenn sie bisher nur als Teil einer Zuweisungsanweisung verwendet wurden.Await expressions can appear almost anywhere in your code, even though up to now, you've only seen them as part of an assignment statement.

Zweitens wird der as-Operator vom Kompilierzeittyp object in List<repo> konvertiert.Secondly, the as operator converts from the compile time type of object to List<repo>. Die Deklaration von ReadObject(Stream) deklariert, dass sie ein Objekt des Typs zurückgibt System.Object.The declaration of ReadObject(Stream) declares that it returns an object of type System.Object. ReadObject(Stream)den Typ, die Sie angegeben werden, wenn Sie es erstellt zurück (List<repo> in diesem Lernprogramm).ReadObject(Stream) will return the type you specified when you constructed it (List<repo> in this tutorial). Wenn die Konvertierung nicht erfolgreich ist, wird der as-Operator als null ausgewertet, statt eine Ausnahme auszulösen.If the conversion does not succeed, the as operator evaluates to null, instead of throwing an exception.

Dieser Abschnitt ist fast fertig.You're almost done with this section. Nachdem Sie nun die JSON-Daten in C#-Objekte konvertiert haben, lassen Sie uns den Namen jedes Repositorys anzeigen.Now that you've converted the JSON to C# objects, let's display the name of each repository. Ersetzen Sie diese Zeilen:Replace the lines that read:

var msg = await stringTask;   //**Deleted this
Console.Write(msg);

...durch die folgenden:with the following:

foreach (var repo in repositories)
    Console.WriteLine(repo.name);

Kompilieren Sie die Anwendung, und führen Sie sie aus.Compile and run the application. Die Anwendung gibt die Namen der Repositorys aus, die Teil der .NET Foundation sind.It will print out the names of the repositories that are part of the .NET Foundation.

Steuern der SerialisierungControlling Serialization

Bevor Sie weitere Features hinzufügen, lassen Sie uns den repo-Typ bearbeiten, sodass er eher den Standardkonventionen von C# entspricht.Before you add more features, let's address the repo type and make it follow more standard C# conventions. Sie erreichen dies, indem Sie den repo-Typ mit Attributen versehen, die die Funktionsweise des JSON-Serialisierungsprogramms steuern.You'll do this by annotating the repo type with attributes that control how the JSON Serializer works. In diesem Fall verwenden Sie die Attribute, um eine Zuordnung zwischen den JSON-Schlüsselnamen und den Namen der C#-Klassen und -Members zu definieren.In your case, you'll use these attributes to define a mapping between the JSON key names and the C# class and member names. Die zwei verwendeten Attribute sind DataContract und DataMember.The two attributes used are the DataContract attribute and the DataMember attribute. Laut Konvention enden alle Attributklassen auf das Suffix Attribute.By convention, all Attribute classes end in the suffix Attribute. Sie müssen dieses Suffix jedoch nicht verwenden, wenn Sie ein Attribut anwenden.However, you do not need to use that suffix when you apply an attribute.

Die Attribute DataContract und DataMember befinden sich in einer anderen Bibliothek, deshalb müssen Sie Ihrer C#-Projektdatei diese Bibliothek als abhängige Komponente hinzufügen.The DataContract and DataMember attributes are in a different library, so you'll need to add that library to your C# project file as a dependency. Fügen Sie dem Abschnitt <ItemGroup> Ihrer Projektdatei die folgende Zeile hinzu:Add the following line to the <ItemGroup> section of your project file:

<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />

Nachdem Sie die Datei speichern, führen Sie dotnet restore (Siehe Hinweis) zum Abrufen dieses Pakets.After you save the file, run dotnet restore (see note) to retrieve this package.

Öffnen Sie dann die Datei repo.cs.Next, open the repo.cs file. Jetzt ändern wir den Namen in die Pascal-Schreibweise und schreiben den Namen Repository vollständig aus.Let's change the name to use Pascal Case, and fully spell out the name Repository. JSON-repo-Knoten sollen weiterhin diesem Typ zugeordnet werden, deshalb müssen Sie das DataContract-Attribut zur Klassendeklaration hinzufügen.We still want to map JSON 'repo' nodes to this type, so you'll need to add the DataContract attribute to the class declaration. Sie legen die Name-Eigenschaft des Attributs auf den Namen der JSON-Knoten fest, die diesem Typ zugeordnet sind:You'll set the Name property of the attribute to the name of the JSON nodes that map to this type:

[DataContract(Name="repo")]
public class Repository

DataContractAttribute ist ein Member des System.Runtime.Serialization -Namespace, deshalb müssen Sie oben in der Datei die geeignete using -Anweisung hinzufügen:The DataContractAttribute is a member of the System.Runtime.Serialization namespace, so you'll need to add the appropriate using statement at the top of the file:

using System.Runtime.Serialization;

Sie haben den Namen der repo-Klasse in Repository geändert, deshalb müssen Sie die gleiche Namensänderung in „Program.cs“ durchführen (einige Editoren unterstützen möglicherweise ein Refactoring mit Umbenennung, wodurch diese Änderung automatisch durchgeführt wird):You changed the name of the repo class to Repository, so you'll need to make the same name change in Program.cs (some editors may support a rename refactoring that will make this change automatically:)

var serializer = new DataContractJsonSerializer(typeof(List<Repository>));

// ...

var repositories = serializer.ReadObject(await streamTask) as List<Repository>;

Führen wir jetzt die gleiche Änderung mit dem name-Feld unter Verwendung der DataMemberAttribute -Klasse durch.Next, let's make the same change with the name field by using the DataMemberAttribute class. Ändern Sie die Deklaration des name-Felds in „repo.cs“ folgendermaßen ab:Make the following changes to the declaration of the name field in repo.cs:

[DataMember(Name="name")]
public string Name;

Diese Änderung bedeutet, dass Sie den Code ändern müssen, mit dem der Name jedes Repositorys in „program.cs“ geschrieben wird:This change means you need to change the code that writes the name of each repository in program.cs:

Console.WriteLine(repo.Name);

Führen Sie dotnet build und anschließend dotnet run aus, um sicherzustellen, dass die Zuordnungen korrekt sind.Do a dotnet build followed by a dotnet run to make sure you've got the mappings correct. Es sollte dieselbe Ausgabe angezeigt werden wie zuvor.You should see the same output as before. Bevor wir weitere Eigenschaften vom Webserver verarbeiten, lassen Sie uns eine weitere Änderung an der Repository-Klasse durchführen.Before we process more properties from the web server, let's make one more change to the Repository class. Der Name-Member ist ein Feld mit öffentlichem Zugriff.The Name member is a publicly accessible field. Dies ist keine bewährte Vorgehensweise in der objektorientierten Programmierung, deshalb führen wir eine Änderung in eine Eigenschaft durch.That's not a good object-oriented practice, so let's change it to a property. Für unsere Zwecke ist kein spezifischer Code zum Abrufen oder Festlegen der Eigenschaft erforderlich, aber die Änderung in eine Eigenschaft macht es leichter, diese Änderungen später hinzuzufügen, ohne die Lauffähigkeit von Code zu beeinträchtigen, der die Repository-Klasse verwendet.For our purposes, we don't need any specific code to run when getting or setting the property, but changing to a property makes it easier to add those changes later without breaking any code that uses the Repository class.

Entfernen Sie die Felddefinition, und ersetzen Sie sie durch eine automatisch implementierte Eigenschaft:Remove the field definition, and replace it with an auto-implemented property:

public string Name { get; set; }

Der Compiler generiert den Körper der get- und set-Accessors sowie ein privates Feld zum Speichern des Namens.The compiler generates the body of the get and set accessors, as well as a private field to store the name. Dies ähnelt dem folgenden Code, den Sie per Hand eingeben könnten:It would be similar to the following code that you could type by hand:

public string Name 
{ 
    get { return this._name; }
    set { this._name = value; }
}
private string _name;

Führen wir eine weitere Änderung durch, bevor wir neue Features hinzufügen.Let's make one more change before adding new features. Die ProcessRepositories-Methode kann die asynchrone Arbeit erledigen und eine Auflistung der Repositorys zurückgeben.The ProcessRepositories method can do the async work and return a collection of the repositories. Geben wir die List<Repository> über diese Methode zurück, und verschieben wir den Code zum Schreiben dieser Informationen in die Main-Methode.Let's return the List<Repository> from that method, and move the code that writes the information into the Main method.

Ändern Sie die Signatur von ProcessRepositories, um einen Task zurückzugeben, dessen Ergebnis eine Liste mit Repository-Objekten ist:Change the signature of ProcessRepositories to return a task whose result is a list of Repository objects:

private static async Task<List<Repository>> ProcessRepositories()

Geben Sie anschließend einfach die Repositorys zurück, nachdem die JSON-Antwort verarbeitet wurde:Then, just return the repositories after processing the JSON response:

var repositories = serializer.ReadObject(await streamTask) as List<Repository>;
return repositories;

Der Compiler generiert das Task<T>-Objekt für die Rückgabe, weil Sie diese Methode als async markiert haben.The compiler generates the Task<T> object for the return because you've marked this method as async. Ändern wir dann die Main-Methode, sodass sie diese Ergebnisse erfasst und den Namen jedes Repositorys an die Konsole schreibt.Then, let's modify the Main method so that it captures those results and writes each repository name to the console. Ihre Main-Methode sieht nun folgendermaßen aus:Your Main method now looks like this:

public static void Main(string[] args)
{
    var repositories = ProcessRepositories().Result;

    foreach (var repo in repositories)
        Console.WriteLine(repo.Name);
}

Der Zugriff auf die Result-Eigenschaft ist bis zum Abschluss des Tasks blockiert.Accessing the Result property of a Task blocks until the task has completed. Normalerweise wäre es vorzuziehen, wie in der ProcessRepositories-Methode mit await auf den Abschluss des Tasks zu warten, aber das ist in der Main-Methode nicht zulässig.Normally, you would prefer to await the completion of the task, as in the ProcessRepositories method, but that isn't allowed in the Main method.

Einlesen weiterer InformationenReading More Information

Zum Abschluss verarbeiten wir einige weitere Eigenschaften im JSON-Paket, das von der GitHub-API gesendet wird.Let's finish this by processing a few more of the properties in the JSON packet that gets sent from the GitHub API. Sie müssen nicht alle Informationen abrufen, aber das Hinzufügen einiger Eigenschaften veranschaulicht einige weitere Features von C#.You won't want to grab everything, but adding a few properties will demonstrate a few more features of the C# language.

Beginnen wir damit, ein paar weitere einfache Typen in die Definition der Repository-Klasse einzufügen.Let's start by adding a few more simple types to the Repository class definition. Fügen Sie diese Eigenschaften zu dieser Klasse hinzu:Add these properties to that class:

[DataMember(Name="description")]
public string Description { get; set; }

[DataMember(Name="html_url")]
public Uri GitHubHomeUrl { get; set; }

[DataMember(Name="homepage")]
public Uri Homepage { get; set; }

[DataMember(Name="watchers")]
public int Watchers { get; set; }

Diese Eigenschaften verfügen über integrierte Konvertierungen vom Zeichenfolgentyp (dieser ist in den JSON-Paketen enthalten) in den Zieltyp.These properties have built-in conversions from the string type (which is what the JSON packets contain) to the target type. Der Uri -Typ ist Ihnen möglicherweise neu.The Uri type may be new to you. Er repräsentiert einen URI, oder in diesem Fall eine URL.It represents a URI, or in this case, a URL. Im Fall der Uri- und int-Typen wird über die Serialisierungsaktion eine Ausnahme ausgelöst, wenn das JSON-Paket Daten enthält, die nicht in den Zieltyp konvertiert werden können.In the case of the Uri and int types, if the JSON packet contains data that does not convert to the target type, the serialization action will throw an exception.

Aktualisieren Sie nach dem Hinzufügen die Main-Methode, um diese Elemente anzuzeigen:Once you've added these, update the Main method to display those elements:

foreach (var repo in repositories)
{
    Console.WriteLine(repo.Name);
    Console.WriteLine(repo.Description);
    Console.WriteLine(repo.GitHubHomeUrl);
    Console.WriteLine(repo.Homepage);
    Console.WriteLine(repo.Watchers);
    Console.WriteLine();
}

Im letzten Schritt fügen wir jetzt die Informationen für den letzten Pushvorgang hinzu.As a final step, let's add the information for the last push operation. Diese Informationen werden in der JSON-Antwort folgendermaßen formatiert:This information is formatted in this fashion in the JSON response:

2016-02-08T21:27:00Z

Dieses Format entspricht nicht den standardmäßigen .NET-DateTime -Formaten.That format does not follow any of the standard .NET DateTime formats. Deshalb müssen Sie eine benutzerdefinierte Konvertierungsmethode schreiben.Because of that, you'll need to write a custom conversion method. Darüber hinaus möchten Sie wahrscheinlich nicht, dass die unformatierte Zeichenfolge für Benutzer der Repository-Klasse verfügbar gemacht wird.You also probably don't want the raw string exposed to users of the Repository class. Dies kann ebenfalls mithilfe von Attributen gesteuert werden.Attributes can help control that as well. Definieren Sie zunächst eine private-Eigenschaft, die die Zeichenfolgendarstellung des DateTime-Werts in Ihrer Repository-Klasse enthält:First, define a private property that will hold the string representation of the date time in your Repository class:

[DataMember(Name="pushed_at")]
private string JsonDate { get; set; }

Das DataMember-Attribut informiert das Serialisierungsprogramm, dass eine Verarbeitung durchgeführt werden soll, obwohl es sich nicht um einen öffentlichen Member handelt.The DataMember attribute informs the serializer that this should be processed, even though it is not a public member. Als Nächstes müssen Sie eine öffentliche schreibgeschützte Eigenschaft zu schreiben, die die Zeichenfolge eine gültige konvertiert DateTime Objekt und gibt zurück, DateTime:Next, you need to write a public read-only property that converts the string to a valid DateTime object, and returns that DateTime:

[IgnoreDataMember]
public DateTime LastPush
{
    get
    {
        return DateTime.ParseExact(JsonDate, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture);
    }
}

Gehen wir die neuen Konstrukte von oben durch.Let's go over the new constructs above. Das IgnoreDataMember-Attribut weist das Serialisierungsprogramm an, dass dieser Typ nicht aus einem JSON-Objekt gelesen oder geschrieben werden darf.The IgnoreDataMember attribute instructs the serializer that this type should not be read to or written from any JSON object. Diese Eigenschaft enthält nur einen get-Accessor.This property contains only a get accessor. Es ist kein set-Accessor vorhanden.There is no set accessor. So wird eine schreibgeschützte Eigenschaft in C# definiert.That's how you define a read-only property in C#. (Ja, Sie können lesegeschützte Eigenschaften in C# erstellen, aber ihr Wert ist begrenzt.) Die ParseExact(String, String, IFormatProvider) Methode analysiert eine Zeichenfolge und erstellt eine DateTime -Objekt mit einem bereitgestellten Datumsformat und fügt zusätzliche Metadaten, die die DateTime mithilfe einer CultureInfo Objekt.(Yes, you can create write-only properties in C#, but their value is limited.) The ParseExact(String, String, IFormatProvider) method parses a string and creates a DateTime object using a provided date format, and adds additional metadata to the DateTime using a CultureInfo object. Wenn die Analyse nicht erfolgreich ist, löst der Eigenschaftsaccessor eine Ausnahme aus.If the parse operation fails, the property accessor throws an exception.

Zur Verwendung von InvariantCulture müssen Sie den System.Globalization -Namespace zu den using-Anweisungen in repo.cs hinzufügen:To use InvariantCulture, you will need to add the System.Globalization namespace to the using statements in repo.cs:

using System.Globalization;

Abschließend fügen Sie eine weitere Ausgabeanweisung in der Konsole hinzu. Jetzt können Sie diese Anwendung erstellen und erneut ausführen:Finally, add one more output statement in the console, and you're ready to build and run this app again:

Console.WriteLine(repo.LastPush);

Ihre Version sollte nun der abgeschlossenen Version entsprechen.Your version should now match the finished sample.

SchlussfolgerungConclusion

In diesem Tutorial wurde gezeigt, wie Sie Webanforderungen ausführen, das Ergebnis analysieren und Eigenschaften dieser Ergebnisse anzeigen.This tutorial showed you how to make web requests, parse the result, and display properties of those results. Sie haben außerdem neue Pakete als abhängige Komponenten in Ihr Projekt eingefügt.You've also added new packages as dependencies in your project. Sie haben einige der Features von C# kennengelernt, die objektorientierte Verfahren unterstützen.You've seen some of the features of the C# language that support object-oriented techniques.

Hinweis

Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands, such as dotnet build and dotnet run, that require a restore to occur. It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.