Exercice - Utiliser un service REST avec HttpClient

Effectué

Dans le cadre de l’application que les ingénieurs utilisent lors de leurs visites chez les clients, vous devez ajouter une fonction permettant à un ingénieur de rechercher les détails des composants électriques. Ces informations seront conservées dans une base de données et accessibles via un service web REST. Il vous a également été demandé de fournir une interface permettant à un administrateur de créer, supprimer et modifier les détails des composants contenus dans la base de données à l’aide du même service web REST.

Dans cet exercice, vous allez déployer le service web REST sur Azure, puis vérifier que vous pouvez y accéder en utilisant un navigateur web. Ensuite, vous allez ajouter des fonctionnalités à une application existante qui utilise le service web REST pour récupérer, ajouter, supprimer et mettre à jour les détails relatifs aux composants électriques.

Vous allez effectuer cet exercice à l’aide du bac à sable Azure.

Conseil

Vous pouvez utiliser le bouton Copier pour copier des commandes dans le Presse-papiers. Pour coller, cliquez avec le bouton droit sur une nouvelle ligne dans le terminal Cloud Shell et sélectionnez Coller ou utilisez le raccourci clavier Maj+Inser (⌘+V sur macOS).

Déployer le service web REST Composants

  1. Dans la fenêtre Cloud Shell, exécutez la commande suivante pour cloner le référentiel contenant le code de cet exercice, y compris le service web REST Composants :

    git clone https://github.com/microsoftdocs/mslearn-dotnetmaui-consume-rest-services
    
  2. Accédez au dossier Consume-REST-services :

    cd mslearn-dotnetmaui-consume-rest-services/src
    
  3. Exécutez la commande suivante pour déployer le service web Composants à l’aide du bac à sable Azure Cloud Shell. Cette commande rend le service disponible via une URL unique. Notez l’URL qui s’affiche. Vous allez configurer l’application pour qu’elle se connecte au service web à l’aide de cette URL.

    bash initenvironment.sh
    

Examiner le code du service web

Remarque

Vous allez effectuer la suite de cet exercice sur votre ordinateur de développement local.

  1. Sur votre ordinateur, ouvrez une fenêtre d’invite de commandes et clonez le référentiel pour cet exercice. Le code se trouve dans le référentiel net-maui-learn-consume-rest-services.

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

    Remarque

    Il est préférable de cloner ou de télécharger le contenu de l’exercice dans un chemin de dossier court, tel que C:\dev, pour éviter que les fichiers générés par la build dépassent la longueur maximale de chemin.

  2. Accédez au dossier webservice\PartsServer dans votre clone du dépôt, puis ouvrez la solution PartsServer.sln en utilisant Visual Studio ou le dossier dans Visual Studio Code. Cette solution contient une copie du code du service web que vous avez déployé sur Azure au cours de la procédure précédente.

  3. Dans la fenêtre Explorateur de solutions, développez le dossier Modèles. Ce dossier contient deux fichiers :

    • Part.cs. La classe Part représente un composant fourni par le service web REST. Les champs incluent l’ID du composant, son nom, son type, sa date de disponibilité (date de première distribution) ainsi qu’une liste de fournisseurs. La propriété Href renvoie l’URI relatif du composant. Un client REST peut utiliser cet URI pour référencer le composant spécifique dans le service web REST. La propriété Suppliers renvoie la liste des fournisseurs du composant sous forme de chaîne.

    • PartsFactory.cs. La classe PartsFactory initialise la liste des composants fournis par le service, à l’aide d’un petit ensemble de valeurs codées en dur. Dans le monde réel, ces données sont récupérées depuis une base de données.

  4. Dans la fenêtre Explorateur de solutions, développez le dossier Contrôleurs. Ce dossier contient les fichiers suivants :

    • PartsController.cs. La classe PartsController implémente l’API web pour le service. Il inclut des méthodes qui permettent à une application cliente de récupérer la liste de tous les composants(Get), de rechercher les détails d’un composant spécifique en fonction de son ID (version surchargée de Get), de mettre à jour les détails d’un composant(Put), d’ajouter un nouveau composant à la liste (Post) et de supprimer un composant de la liste (Delete).

    • LoginController.cs. La classe LoginController implémente une forme simple d’authentification pour le service web. Une application doit envoyer une requête HTTP GET à ce contrôleur, qui retourne un jeton d’autorisation. Ce jeton d’autorisation est utilisé pour authentifier les requêtes envoyées à PartsController.

    • BaseController.cs. La classe BaseController contient la logique utilisée pour authentifier les requêtes. La classe PartsController hérite de cette classe. Si le client tente d’appeler des méthodes dans la classe PartsController sans fournir de jeton d’authentification valide, les méthodes retournent une réponse HTTP 401 (non autorisée).

Examiner le code de l’application cliente .NET MAUI

Ce module utilise le kit de développement logiciel (SDK) .NET 8.0. Assurez-vous que .NET 8.0 est installé en exécutant la commande suivante dans votre terminal de commandes préféré :

dotnet --list-sdks

Une sortie semblable à l’exemple suivant s’affiche :

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

Vérifiez que la liste comporte une version commençant par 8. S’il n’y en a pas ou que la commande est introuvable, installez la dernière version du kit de développement logiciel (SDK) .NET 8.0.

  1. Fermez la solution PartsServer et ouvrez la solution PartsClient dans le dossier src\client\PartsClient du dépôt cloné. Cette solution contient une implémentation partielle d’une application cliente .NET MAUI utilisant le service web PartsServer.

  2. Dans la fenêtre Explorateur de solutions, développez le dossier Données. Ce dossier contient le code de deux classes :

    • PartsManager.cs. La classe PartsManager fournit les méthodes utilisées par l’application cliente pour interagir avec le service web REST. Actuellement, cette classe est incomplète et vous allez ajouter le code nécessaire au cours de cet exercice. Une fois l’opération terminée, la méthode GetClient se connecte au service web REST. La méthode GetAll retourne une liste de composants à partir du service web REST. La méthode Add ajoute un nouveau composant à la liste des composants gérés par le service web REST. La méthode Update modifie les détails d’un composant stockés par le service web REST, et la méthode Delete supprime un composant.

    • Part.cs. La classe Part modélise un composant stocké dans la base de données. Elle expose les propriétés qu’une application peut utiliser pour accéder aux champs PartID, PartName, PartAvailableDate, PartType et PartSuppliers. La classe fournit également une méthode utilitaire nommée SupplierString qu’une application peut utiliser pour récupérer une chaîne mise en forme contenant les noms des fournisseurs.

  3. Dans la fenêtre Explorateur de solutions, développez le dossier Pages. Ce dossier contient le balisage et le code pour deux pages :

    • PartsPage.xaml. Cette page utilise une disposition CollectionView avec DataTemplate pour afficher les détails des composants disponibles sous forme de liste. DataTemplate utilise la liaison de données pour connecter les données affichées aux composants récupérés à partir du service web. Vous pouvez sélectionner une ligne dans CollectionView pour modifier un composant dans AddPartPage, ou sélectionner le bouton Ajouter un nouveau composant pour ajouter un nouveau composant.

    • AddPartPage.xaml. Cette page permet aux utilisateurs d’entrer et d’enregistrer les détails d’un nouveau composant. Les utilisateurs peuvent spécifier le nom du composant, le type de composant, ainsi qu’un fournisseur initial. L’ID de composant et la date de disponibilité du composant sont générés automatiquement.

  4. Dans la fenêtre Explorateur de solutions, développez le dossier ViewModels. Ce dossier contient deux classes : AddPartViewModel.cs et PartsViewModel.cs. Il s’agit des modèles d’affichage correspondant à leurs pages respectives et contenant les propriétés ainsi que la logique nécessaires à la page pour afficher et manipuler les données.

Se connecter au service

Le service REST exige que vous commenciez par vous connecter pour obtenir un jeton d’autorisation. Il n’y a aucune authentification utilisateur. Vous appelez d’abord un point de terminaison spécifique pour obtenir un jeton d’autorisation, puis vous renvoyez le jeton au serveur sur chaque requête suivante dans l’en-tête HTTP.

  1. Ouvrez le fichier PartsManager.cs du dossier Data.

  2. Ajoutez les champs statiques BaseAddress et Url tels que définis dans l’extrait de code suivant à la classe PartsManager. Remplacez le texte URL GOES HERE par l’URL du service web REST notée précédemment :

    public class PartsManager
    {
        static readonly string BaseAddress = "URL GOES HERE";
        static readonly string Url = $"{BaseAddress}/api/";
        ...
    }
    
  3. Ajoutez le champ suivant à la classe, après le champ Url. Ce champ contiendra le jeton d’autorisation retourné lorsque l’utilisateur se connecte :

    private static string authorizationKey;
    
  4. Recherchez la méthode GetClient. Actuellement, cette méthode lève une exception NotImplementedException. Remplacez le code existant dans cette méthode par le code suivant. Ce code crée un objet HttpClient, puis envoie une requête au point de terminaison login du service web REST. Le service doit répondre par un message qui contient le jeton d’autorisation. Désérialisez ce jeton et ajoutez-le en tant qu’en-tête de requête d’autorisation par défaut pour les demandes suivantes envoyées à l’aide de l’objet HttpClient :

    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;
    }
    

Effectuer une opération GET pour récupérer des informations relatives aux composants

  1. Dans le fichier PartsManager.cs, recherchez la méthode GetAll. Il s’agit d’une méthode asynchrone qui retourne une liste énumérable de composants. Cette méthode n’est pas encore implémentée.

  2. Dans cette méthode, supprimez le code qui lève l’exception NotImplementedException.

  3. Vérifiez si l’appareil dispose d’une connectivité Internet à l’aide de la classe Connectivity. En l’absence de connectivité Internet, retournez un List<Part> vide.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return new List<Part>();
    
  4. Appelez la méthode GetClient pour récupérer un objet HttpClient à utiliser. N’oubliez pas que GetClient est asynchrone. Aussi, utilisez l’opérateur Await pour capturer l’objet retourné par cette méthode.

  5. Appelez la méthode GetStringAsync de l’objet HttpClient et fournissez l’URL de base pour récupérer un tableau de composants à partir du service web REST. Les données sont retournées de façon asynchrone sous forme de chaîne JSON.

  6. Désérialisez la chaîne JSON retournée par cette méthode en une liste d’objets Part en utilisant la méthode JsonSerializer.Deserialize. Retournez cette liste à l’appelant.

    La méthode terminée doit se présenter comme suit :

    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. Générez et exécutez l'application. Au démarrage de l’application, la page Part List s’affiche et la liste des composants récupérés par la méthode GetAll doit apparaître. L’image suivante montre l’application en cours d’exécution sur Android :

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

  8. Quand vous avez fini de parcourir les données, fermez l’application et revenez à Visual Studio ou à Visual Studio Code.

Effectuer une opération POST pour ajouter un nouveau composant à la base de données

  1. Dans la classe PartsManager, recherchez la méthode Add. Cette méthode dispose de paramètres pour le nom du composant, un fournisseur et le type de composant. Cette méthode est asynchrone. Cette méthode a pour objectif d’insérer un nouveau composant dans la base de données et de retourner un objet Part représentant l’élément nouvellement créé.

  2. Supprimez le code existant dans la méthode.

  3. Vérifiez si l’appareil dispose d’une connectivité Internet à l’aide de la classe Connectivity. En l’absence de connectivité Internet, retournez un Part vide.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return new Part();
    
  4. Créez un objet Part. Renseignez les champs à l’aide des données transmises :

    • Définissez le champ PartID sur une chaîne vide. Cet ID est généré par le service web REST.
    • Créez une Liste pour contenir le nom du fournisseur.
    • Définissez le champ PartAvailableDate sur DateTime.Now.
    • Obtenez un client HTTP à partir de la méthode GetClient.
    var part = new Part()
    {
        PartName = partName,
        Suppliers = new List<string>(new[] { supplier }),
        PartID = string.Empty,
        PartType = partType,
        PartAvailableDate = DateTime.Now.Date
    };
    
  5. Appelez la méthode GetClient pour récupérer un objet HttpClient à utiliser.

  6. Créez un objet HttpRequestMessage. Cet objet est utilisé pour modéliser la requête envoyée au service web. Lancez-la avec des paramètres indiquant le verbe HTTP à utiliser et l’URL du service web avec lequel communiquer.

    var msg = new HttpRequestMessage(HttpMethod.Post, $"{Url}parts");
    
  7. Vous devez envoyer une charge utile au service web avec les informations Part à créer. Cette charge utile sera sérialisée en JSON. La charge utile JSON est ajoutée à la propriété HttpRequestMessage.Content et sérialisée avec la méthode JsonContent.Create.

    msg.Content = JsonContent.Create<Part>(part);
    
  8. Envoyez à présent le message au service web avec la fonction HttpClient.SendAsync. Cette fonction retourne un objet HttpResponseMessage contenant des informations relatives à l’opération sur le serveur. Il peut s’agir des codes de réponse HTTP et des informations transmises à partir du serveur.

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

    Notez que l’exemple précédent utilise la méthode response.EnsureSuccessStatusCode. Cela entraînera une erreur si un code d'état HTTP autre que 2xx est renvoyé.

  9. Si le service web retourne des informations, telles qu’un objet sérialisé en JSON, vous pouvez les lire à partir de HttpResponseMessage. Ensuite, vous pouvez désérialiser le JSON à l’aide de JsonSerializer.Deserialize.

    var returnedJson = await response.Content.ReadAsStringAsync();
    
    var insertedPart = JsonSerializer.Deserialize<Part>(returnedJson, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            });
    
  10. Enfin, retournez le nouveau Composant inséré.

    return insertedPart;
    
  11. Générez et exécutez l'application. Sélectionnez le bouton Ajouter un nouveau composant, puis entrez un nom, un type et un fournisseur pour créer un composant. Sélectionnez Enregistrer. La méthode Add de la classe PartsManager est appelée, ce qui crée le composant dans le service web. Si l’opération réussit, la page correspondant à la liste des composants réapparaît avec le nouveau composant en bas de la liste.

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

  12. Quand vous avez fini de parcourir les données, fermez l’application et revenez à Visual Studio ou à Visual Studio Code.

Effectuer une opération PUT pour mettre à jour les détails relatifs à un composant dans la base de données

  1. Dans la classe PartsManager, recherchez la méthode Update. Il s’agit d’une méthode asynchrone qui utilise un objet Part en tant que paramètre. La méthode ne possède pas de valeur renvoyée explicite. Pour autant, le type de retour est Task afin que les exceptions soient correctement retournées à l’appelant. Implémentons la fonctionnalité PUT.

  2. Supprimez le code existant.

  3. Comme précédemment, recherchez une connexion Internet.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return;
    
  4. Créez un HttpRequestMessage, en spécifiant cette fois une opération PUT et l’URL de mise à jour des composants.

    HttpRequestMessage msg = new(HttpMethod.Put, $"{Url}parts/{part.PartID}");
    
  5. Définissez la propriété Content de HttpRequestMessage à l’aide de la fonction JsonContent.Create et du paramètre part transmis à la fonction.

    msg.Content = JsonContent.Create<Part>(part);
    
  6. Obtenez un client HTTP à partir de la méthode GetClient.

    var client = await GetClient();
    
  7. Envoyez la requête avec HttpClient, puis assurez-vous qu’elle a réussi.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    
  8. Générez et exécutez l'application. Sélectionnez l’un des composants de la liste. La page AddPart s’affiche. Cette fois, les propriétés sont déjà renseignées. Procédez aux mises à jour souhaitées.

  9. Sélectionnez Enregistrer. Cela appelle la méthode Update de la classe PartsManager pour envoyer les modifications au service web. Si elle réussit, la page de liste de composants réapparaît avec vos modifications.

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

    Remarque

    Le composant que vous avez ajouté à la tâche précédente n’apparaît pas sur la page Liste des composants . Les données que l’application utilise sont réinitialisées à une liste de composants prédéfinis chaque fois que l’application s’exécute. Cela permet d’assurer une certaine cohérence pour le test de l’application.

Effectuer une opération DELETE pour supprimer les détails d’un composant de la base de données

  1. Dans la classe PartsManager, recherchez la méthode Delete. Il s’agit d’une méthode asynchrone qui utilise une chaîne partId et retourne une Tâche.

  2. Supprimez le code existant.

  3. Recherchez une connexion Internet.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return;
    
  4. Créez un objet HttpRequestMessage. Spécifiez uniquement le verbe HTTP DELETE et l’URL pour supprimer un composant.

    HttpRequestMessage msg = new(HttpMethod.Delete, $"{Url}parts/{partID}");
    
  5. Obtenez un client HTTP à partir de la méthode GetClient.

    var client = await GetClient();
    
  6. Envoyez la requête au service web. Vérifiez qu’elle aboutit.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    
  7. Générez et exécutez l'application. Sélectionnez un composant dans la liste, puis sélectionnez Supprimer sur la page Ajouter un composant. En cas de réussite, la page Liste des composants réapparaît et le composant supprimé n’est plus visible.