Übung: Nutzen eines REST-Diensts mit HttpClient

Abgeschlossen

Als Teil der App, die Techniker*innen bei Kundenbesuchen verwenden, müssen Sie eine Funktion hinzufügen, mit der ein*e Techniker*in die Details von elektrischen Komponenten nachschlagen kann. Diese Informationen werden in einer Datenbank gespeichert und über einen REST-Webdienst zugänglich gemacht. Sie wurden auch gebeten, eine Schnittstelle bereitzustellen, die es Administrator*innen ermöglicht, die Details der in der Datenbank gespeicherten Teile über denselben REST-Webdienst zu erstellen, zu entfernen und zu ändern.

In dieser Übung werden Sie den REST-Webdienst in Azure bereitstellen und dann überprüfen, ob Sie mit einem Webbrowser darauf zugreifen können. Dann fügen Sie einer bestehenden App Funktionen hinzu, die den REST-Webservice zum Abrufen, Hinzufügen, Löschen und Aktualisieren der Details von elektrischen Komponenten verwenden.

Sie führen diese Übung mithilfe der Azure-Sandbox aus.

Tipp

Mit der Schaltfläche Kopieren können Sie Befehle in die Zwischenablage kopieren. Klicken Sie zum Einfügen im Cloud Shell-Terminal mit der rechten Maustaste auf eine neue Zeile, und wählen Sie dann Einfügen aus, oder verwenden Sie die Tastenkombination UMSCHALT+EINFG (⌘+V unter macOS).

Bereitstellen des REST-Webdiensts für Komponenten („Parts“)

  1. Führen Sie im Cloud Shell-Fenster den folgenden Befehl aus, um das Repository zu klonen, das den Code für diese Übung enthält, einschließlich des REST-Webdiensts für Komponenten („Parts“):

    git clone https://github.com/microsoftdocs/mslearn-dotnetmaui-consume-rest-services
    
  2. Navigieren zum Ordner Consume-REST-Dienste

    cd mslearn-dotnetmaui-consume-rest-services/src
    
  3. Führen Sie den folgenden Befehl aus, um den Parts-Webdienst über die Azure Cloud Shell-Sandbox bereitzustellen. Dieser Befehl stellt den Dienst über eine eindeutige URL zur Verfügung. Notieren Sie sich diese URL, wenn sie angezeigt wird. Sie konfigurieren die App so, dass eine Verbindung mit dem Webdienst über diese URL hergestellt wird.

    bash initenvironment.sh
    

Überprüfen des Codes für den Webdienst

Hinweis

Sie führen den Rest dieser Übung auf Ihrem lokalen Entwicklungscomputer aus.

  1. Öffnen Sie auf Ihrem Computer ein Fenster der Eingabeaufforderung und klonen Sie das Repository für diese Übung. Der Code befindet sich im Repository net-maui-learn-consume-rest-services.

    git clone https://github.com/microsoftdocs/mslearn-dotnetmaui-consume-rest-services
    

    Hinweis

    Es empfiehlt sich, den Übungsinhalt in einen kurzen Ordnerpfad wie z. B. „C:\dev“ zu klonen oder herunterzuladen. So vermeiden Sie, dass vom Build generierte Dateien die maximale Pfadlänge überschreiten.

  2. Gehen Sie zum Ordner src\webservice\PartsServer in Ihrem Repositoryklon, und öffnen Sie die Lösung PartsServer.sln mit Visual Studio, oder öffnen Sie den Ordner in Visual Studio Code. Diese Projektmappe enthält eine Kopie des Codes für den Webdienst, den Sie im vorherigen Verfahren in Azure bereitgestellt haben.

  3. Erweitern Sie im Fenster „Projektmappen-Explorer“ den Ordner Models. Dieser Ordner enthält zwei Dateien:

    • Part.cs. Die Part-Klasse stellt eine Komponente dar, die vom REST-Webdienst bereitgestellt wird. Zu den Feldern gehören die Komponenten-ID, der Komponentenname, der Komponententyp, das Verfügbarkeitsdatum (wann die Komponente zum ersten Mal bereitgestellt wurde) und eine Liste der Lieferanten. Die Href-Eigenschaft gibt den relativen URI der Komponente zurück. Ein REST-Client kann diesen URI verwenden, um auf diese bestimmte Komponente im REST-Webdienst zu verweisen. Die Suppliers-Eigenschaft gibt die Liste der Lieferanten der Komponente als Zeichenfolge zurück.

    • PartsFactory.cs. Die PartsFactory-Klasse initialisiert die Liste der vom Dienst bereitgestellten Komponenten mithilfe einer kleinen Sammlung hartcodierter Werte. In der realen Welt würden diese Daten aus einer Datenbank abgerufen.

  4. Erweitern Sie im Fenster „Projektmappen-Explorer“ den Ordner Controllers. Dieser Ordner enthält die folgenden Dateien:

    • PartsController.cs. Die PartsController-Klasse implementiert die Web-API für den Dienst. Sie enthält Methoden, die es einer Clientanwendung ermöglichen, eine Liste aller Komponenten abzurufen (Get), die Details einer bestimmten Komponente anhand der Komponenten-ID (der überladenen Version von Get) zu finden, die Details einer Komponente zu aktualisieren (Put), der Liste eine neue Komponente hinzuzufügen (Post) und eine Komponente aus der Liste zu entfernen (Delete).

    • LoginController.cs. Die LoginController-Klasse implementiert eine einfache Form von Authentifizierung für den Webdienst. Eine App muss eine HTTP GET-Anforderung an diesen Controller senden, die ein Autorisierungstoken zurückgibt. Dieses Autorisierungstoken wird verwendet, um die an den PartsController gesendeten Anforderungen zu authentifizieren.

    • BaseController.cs. Die BaseController-Klasse enthält die Logik, die zum Authentifizieren von Anforderungen verwendet wird. Die PartsController-Klasse erbt von dieser Klasse. Wenn der Client versucht, Methoden in der PartsController-Klasse aufzurufen, ohne ein gültiges Authentifizierungstoken bereitzustellen, geben die Methoden eine HTTP 401-Antwort (Nicht autorisiert) zurück.

Untersuchen des Codes für die .NET MAUI-Client-App

In diesem Modul wird das .NET 8.0 SDK verwendet. Stellen Sie sicher, dass .NET 8.0 installiert ist, indem Sie in Ihrem bevorzugten Befehlsterminal den folgenden Befehl ausführen:

dotnet --list-sdks

Die daraufhin angezeigte Ausgabe sieht in etwa wie im folgenden Beispiel aus:

6.0.317 [C:\Program Files\dotnet\sdk]
7.0.401 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]

Stellen Sie sicher, dass eine Version aufgeführt wird, die mit 8 beginnt. Wenn nichts aufgeführt ist oder der Befehl nicht gefunden wurde, installieren Sie das neueste .NET 8.0 SDK.

  1. Schließen Sie die Lösung PartsServer, und öffnen Sie die Lösung PartsClient im Ordner src\client\PartsClient im geklonten Repository. Diese Projektmappe enthält eine teilweise Implementierung einer .NET MAUI-Client-App, die den PartsServer-Webdienst verwendet.

  2. Erweitern Sie im Projektmappen-Explorer-Fenster den Ordner Daten. Dieser Ordner enthält den Code für zwei Klassen:

    • PartsManager.cs. Die PartsManager-Klasse stellt die Methoden bereit, die die Client-App für die Interaktion mit dem REST-Webdienst verwendet. Diese Klasse ist derzeit unvollständig. Sie fügen den erforderlichen Code während dieser Übung hinzu. Wenn der Code vollständig ist, stellt die GetClient-Methode eine Verbindung mit dem REST-Webdienst her. Die GetAll-Methode gibt eine Liste der Komponenten aus dem REST-Webdienst zurück. Die Add-Methode fügt der Liste der vom REST-Webdienst verwalteten Komponenten eine neue Komponente hinzu. Die Update-Methode ändert die Details eines vom REST-Webservice gespeicherten Teils, und die Delete-Methode entfernt einen Teil.

    • Part.cs. Die Part-Klasse modelliert eine in der Datenbank gespeicherte Komponente. Sie macht Eigenschaften verfügbar, die eine Anwendung für den Zugriff auf die Felder PartID, PartName, PartAvailableDate, PartType und PartSuppliers verwenden kann. Die Klasse stellt auch eine Hilfsmethode namens SupplierString bereit, mit der eine Anwendung eine formatierte Zeichenfolge mit den Lieferantennamen abrufen kann.

  3. Erweitern Sie im Fenster „Projektmappen-Explorer“ den Ordner Pages. Dieser Ordner enthält das Markup und den Code für zwei Seiten:

    • PartsPage.xaml. Diese Seite verwendet ein CollectionView-Layout mit einer DataTemplate, um die Details der verfügbaren Komponenten als Liste anzuzeigen. DataTemplate verwendet die Datenbindung, um die angezeigten Daten mit den vom Webdienst abgerufenen Komponenten zu verbinden. Sie können in CollectionView eine Zeile auswählen, um ein Teil auf AddPartPage zu bearbeiten, oder Sie können auf die Schaltfläche Neuen Teil hinzufügen klicken, um einen neuen Teil hinzuzufügen.

    • AddPartPage.xaml. Auf dieser Seite können Benutzer*innen die Details für ein neues Teil eingeben und speichern. Benutzer*innen können den Artikelnamen, den Artikeltyp und einen ersten Anbieter angeben. Die Komponenten-ID und das verfügbare Datum der Komponente werden automatisch generiert.

  4. Erweitern Sie im Fenster „Projektmappen-Explorer“ den Ordner ViewModels. Dieser Ordner enthält zwei Klassen: AddPartViewModel.cs und PartsViewModel.cs. Diese sind die Ansichtsmodelle für die jeweiligen Seiten und enthalten Eigenschaften und Logik, die die Seite zur Anzeige und Bearbeitung von Daten benötigt.

Anmelden beim Dienst

Der REST-Dienst erfordert, dass Sie sich zunächst anmelden, um ein Autorisierungstoken abzurufen. Es gibt keine Benutzerauthentifizierung. Sie rufen zunächst einen bestimmten Endpunkt auf, um ein Autorisierungs-Token zu erhalten, und senden dann das Token bei jeder nachfolgenden Anforderung im HTTP-Header an den Server zurück.

  1. Öffnen Sie die Datei PartsManager.cs im Ordner Data.

  2. Fügen Sie die statischen Felder BaseAddress und Url der PartsManager-Klasse wie im folgenden Codeausschnitt definiert hinzu. Ersetzen Sie den Text URL GOES HERE durch die URL des REST-Webdiensts, die Sie sich zuvor notiert haben:

    public class PartsManager
    {
        static readonly string BaseAddress = "URL GOES HERE";
        static readonly string Url = $"{BaseAddress}/api/";
        ...
    }
    
  3. Fügen Sie der Klasse nach dem Feld Url das folgende Feld hinzu. Dieses Feld enthält das Autorisierungstoken, das zurückgegeben wird, wenn sich der Benutzer anmeldet:

    private static string authorizationKey;
    
  4. Suchen Sie nach der GetClient-Methode. Diese Methode löst derzeit eine NotImplementedException-Ausnahme aus. Ersetzen Sie den vorhandenen Code in dieser Methode durch den folgenden Code. Dieser Code erstellt ein HttpClient-Objekt und sendet dann eine Anforderung an den Login-Endpunkt des REST-Webdienstes. Der Dienst sollte mit einer Nachricht antworten, die das Autorisierungstoken enthält. Deserialisieren Sie dieses Token, und fügen Sie es als standardmäßigen Autorisierungsanforderungsheader für nachfolgende Anforderungen hinzu, die mit dem HttpClient-Objekt gesendet werden:

    private static async Task<HttpClient> GetClient()
    {
        if (client != null)
            return client;
    
        client = new HttpClient();
    
        if (string.IsNullOrEmpty(authorizationKey))
        {                
            authorizationKey = await client.GetStringAsync($"{Url}login");
            authorizationKey = JsonSerializer.Deserialize<string>(authorizationKey);
        }
    
        client.DefaultRequestHeaders.Add("Authorization", authorizationKey);
        client.DefaultRequestHeaders.Add("Accept", "application/json");
    
        return client;
    }
    

Ausführen eines GET-Vorgangs zum Abrufen von Informationen für Komponenten

  1. Suchen Sie in der Datei PartsManager.cs nach der GetAll-Methode. Dies ist eine asynchrone Methode, die eine aufzählbare Liste von Komponenten zurückgibt. Diese Methode ist noch nicht implementiert.

  2. Löschen Sie in dieser Methode den Code, der die NotImplementedException-Ausnahme auslöst.

  3. Überprüfen Sie, ob das Gerät über Internetzugang verfügt, indem Sie die Connectivity-Klasse verwenden. Wenn kein Internet verfügbar ist, geben Sie einen leeres List<Part>-Element zurück.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return new List<Part>();
    
  4. Rufen Sie die GetClient-Methode auf, um ein HttpClient-Objekt abzurufen, mit dem Sie arbeiten können. Denken Sie daran, dass GetClient asynchron ist. Verwenden Sie daher den await-Operator, um das von dieser Methode zurückgegebene Objekt zu erfassen.

  5. Rufen Sie die GetStringAsync-Methode des HttpClient-Objekts auf, und geben Sie die Basis-URL an, um ein Array von Komponenten aus dem REST-Webdienst abzurufen. Die Daten werden asynchron als JSON-Zeichenfolge zurückgegeben.

  6. Deserialisieren Sie mithilfe der JsonConvert.Deserialize-Methode die von der vorherigen Methode zurückgegebene JSON-Zeichenfolge in eine Liste von Part-Objekten. Geben Sie diese Liste an den Aufrufer zurück.

    Die vollständige Methode sollte so aussehen:

    public static async Task<IEnumerable<Part>> GetAll()
    {
        if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
            return new List<Part>();
    
        var client = await GetClient();
        string result = await client.GetStringAsync($"{Url}parts");
    
        return JsonSerializer.Deserialize<List<Part>>(result, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            });                     
    }
    
  7. Erstellen Sie die App, und führen Sie sie aus. Wenn die App gestartet wird, wird die Seite „Part List“ angezeigt, und eine Liste der von der GetAll-Methode abgerufenen Komponenten sollte angezeigt werden. Die folgende Abbildung zeigt die App, die unter Android ausgeführt wird:

    A screenshot of the Parts Client app running on Android showing a list of parts.

  8. Wenn Sie mit dem Durchsuchen der Daten fertig sind, schließen Sie die App, und kehren Sie zu Visual Studio oder Visual Studio Code zurück.

Ausführen eines POST-Vorgangs zum Hinzufügen einer neuen Komponente zur Datenbank

  1. Suchen Sie in der PartManager-Klasse nach der Add-Methode. Diese Methode enthält Parameter für den Komponentennamen, einen Lieferanten und den Komponententyp. Die Methode ist asynchron. Die Methode dient dazu, ein neues Teil in die Datenbank einzufügen und ein Part-Objekt zurückzugeben, das das neu erstellte Element darstellt.

  2. Löschen Sie den vorhandenen Code in der Methode.

  3. Überprüfen Sie, ob das Gerät über Internetzugang verfügt, indem Sie die Connectivity-Klasse verwenden. Wenn kein Internet verfügbar ist, geben Sie einen leeres Part-Element zurück.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return new Part();
    
  4. Erstellen Sie ein neues Part-Objekt. Füllen Sie die Felder mit den übergebenen Daten auf:

    • Legen Sie das PartID-Feld auf eine leere Zeichenfolge fest. Diese ID wird vom REST-Webdienst generiert.
    • Erstellen Sie ein neues List-Element, das den Namen des Lieferanten enthält.
    • Legen Sie das PartAvailableDate-Feld auf DateTime.Now fest.
    • Rufen Sie einen HTTP-Client aus der GetClient-Methode ab.
    var part = new Part()
    {
        PartName = partName,
        Suppliers = new List<string>(new[] { supplier }),
        PartID = string.Empty,
        PartType = partType,
        PartAvailableDate = DateTime.Now.Date
    };
    
  5. Rufen Sie die GetClient-Methode auf, um ein HttpClient-Objekt abzurufen, mit dem Sie arbeiten können.

  6. Erstellen Sie ein HttpRequestMessage-Objekt. Dieses Objekt wird verwendet, um die Anforderung zu modellieren, die an den Webdienst gesendet wird. Initialisieren Sie es mit Parametern, die das zu verwendende HTTP-Verb und die URL des Webdiensts angeben, mit dem kommuniziert werden soll.

    var msg = new HttpRequestMessage(HttpMethod.Post, $"{Url}parts");
    
  7. Sie müssen Nutzdaten mit den zu erstellenden Part-Informationen an den Webdienst senden. Diese Nutzdaten werden in JSON serialisiert. Die JSON-Nutzdaten werden der HttpRequestMessage.Content-Eigenschaft hinzugefügt, und sie wird mit der JsonContent.Create-Methode serialisiert.

    msg.Content = JsonContent.Create<Part>(part);
    
  8. Senden Sie die Nachricht nun mit der HttpClient.SendAsync-Funktion an den Webdienst. Diese Funktion gibt ein HttpResponseMessage-Objekt zurück, das Informationen zum Vorgang auf dem Server enthält. Dies sind beispielsweise HTTP-Antwortcodes und Informationen, die vom Server zurückgegeben werden.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    

    Beachten Sie, dass oben die Methode response.EnsureSuccessStatusCode verwendet wird. Dadurch wird ein Fehler ausgelöst, wenn etwas anderes als ein 2xx-HTTP-Statuscode zurückgegeben wird.

  9. Wenn der Webdienst Informationen zurückgibt, wie z. B. ein in JSON serialisiertes Objekt, können Sie diese aus HttpResponseMessage auslesen. Anschließend können Sie den JSON-Code mit JsonSerializer.Deserializedeserialisieren.

    var returnedJson = await response.Content.ReadAsStringAsync();
    
    var insertedPart = JsonSerializer.Deserialize<Part>(returnedJson, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            });
    
  10. Geben Sie schließlich das neue eingefügte Part-Element zurück.

    return insertedPart;
    
  11. Erstellen Sie die App, und führen Sie sie aus. Wählen Sie die Schaltfläche Add New Part (Neue Komponente hinzufügen) aus, und geben Sie einen Namen, einen Typ und einen Lieferanten ein, um eine neue Komponente zu erstellen. Wählen Sie Speichern aus. Die Add-Methode in der PartsManager-Klasse wird aufgerufen, wodurch die neue Komponente im Webdienst erstellt wird. Wenn der Vorgang erfolgreich ist, wird die Seite mit der Komponentenliste mit der neuen Komponente am Ende der Liste erneut angezeigt.

    A screenshot of the app running after a new part has been added. The new part is at the bottom of the list.

  12. Wenn Sie mit dem Durchsuchen der Daten fertig sind, schließen Sie die App, und kehren Sie zu Visual Studio oder Visual Studio Code zurück.

Ausführen eines PUT-Vorgangs zum Aktualisieren der Details für eine Komponente in der Datenbank

  1. Suchen Sie in der PartsManager-Klasse nach der Update-Methode. Dies ist eine asynchrone Methode, die ein Part-Objekt als Parameter annimmt. Die Methode hat keinen expliziten Rückgabewert. Der Rückgabetyp ist jedoch Task, sodass Ausnahmen ordnungsgemäß an den Aufrufer zurückgegeben werden. Implementieren wir die PUT-Funktionalität.

  2. Löschen Sie den vorhandenen Code.

  3. Überprüfen Sie wie zuvor, ob eine Internetverbindung vorhanden ist.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return;
    
  4. Erstellen Sie eine neue HttpRequestMessage. Dieses Mal geben Sie einen PUT-Vorgang und die URL zum Aktualisieren von Komponenten an.

    HttpRequestMessage msg = new(HttpMethod.Put, $"{Url}parts/{part.PartID}");
    
  5. Legen Sie die Content-Eigenschaft von HttpRequestMessage mit der JsonContent.Create-Funktion und dem part-Parameter fest, der an die Funktion übergeben wurde.

    msg.Content = JsonContent.Create<Part>(part);
    
  6. Rufen Sie einen HTTP-Client aus der GetClient-Methode ab.

    var client = await GetClient();
    
  7. Senden Sie die Anforderung mit dem HttpClient, und stellen Sie dann sicher, dass sie erfolgreich war.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    
  8. Erstellen Sie die App, und führen Sie sie aus. Wählen Sie eines der Teile aus der Liste. Die Seite AddPart wird angezeigt. Dieses Mal sind die Eigenschaften bereits ausgefüllt. Aktualisieren Sie alle gewünschten Angaben.

  9. Wählen Sie Speichern aus. Dadurch wird die Update-Methode in der PartsManager-Klasse aufgerufen, um die Änderungen an den Webdienst zu senden. Wenn der Vorgang erfolgreich ist, wird erneut die Komponentenliste angezeigt, die nun Ihre Änderungen enthält.

    A screenshot of the app running with the first item in the list updated.

    Hinweis

    Die Komponente, die Sie im vorherigen Schritt hinzugefügt haben, wird nicht auf der Seite Part List angezeigt. Die von der App verwendeten Daten werden bei jeder Ausführung der App auf eine Liste mit vordefinierten Teilen zurückgesetzt. Dadurch wird Konsistenz beim Testen der App bereitgestellt.

Ausführen eines DELETE-Vorgangs, um die Details für eine Komponente aus der Datenbank zu entfernen

  1. Suchen Sie in der PartsManager-Klasse nach der Delete-Methode. Dies ist eine asynchrone Methode, die eine partId-Zeichenfolge annimmt und einen Task zurückgibt.

  2. Löschen Sie den vorhandenen Code.

  3. Überprüfen Sie, ob eine Internetverbindung vorhanden ist.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return;
    
  4. Erstellen Sie ein neues HttpRequestMessage-Objekt. Geben Sie jetzt nur das HTTP-Verb DELETE und die URL zum Löschen einer Komponente an.

    HttpRequestMessage msg = new(HttpMethod.Delete, $"{Url}parts/{partID}");
    
  5. Rufen Sie einen HTTP-Client aus der GetClient-Methode ab.

    var client = await GetClient();
    
  6. Senden Sie die Anforderung an den Webdienst. Überprüfen Sie nach der Rückgabe den Erfolg.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    
  7. Erstellen Sie die App, und führen Sie sie aus. Wählen Sie einen Teil aus der Liste und klicken Sie dann Löschen auf der Seite Part hinzufügen. Bei Erfolg wird erneut die Seite Part List (Komponentenliste) angezeigt, und die gelöschte Komponente ist nicht mehr sichtbar.