Övning – Använda en REST-tjänst med HttpClient

Slutförd

Som en del av appen som tekniker använder vid kundbesök måste du lägga till en funktion som gör att en tekniker kan söka efter information om elektriska komponenter. Den här informationen lagras i en databas och nås via en REST-webbtjänst. Du har också blivit ombedd att ange ett gränssnitt som gör att en administratör kan skapa, ta bort och ändra information om de delar som finns i databasen med samma REST-webbtjänst.

I den här övningen distribuerar du REST-webbtjänsten till Azure och kontrollerar sedan att du kan komma åt den med hjälp av en webbläsare. Sedan lägger du till funktioner i en befintlig app som använder REST-webbtjänsten för att hämta, lägga till, ta bort och uppdatera information om elektriska komponenter.

Du utför den här övningen med hjälp av Sandbox-miljön i Azure.

Dricks

Du kan använda knappen Kopiera till att kopiera kommandon till Urklipp. Om du vill klistra in högerklickar du på en ny rad i Cloud Shell-terminalen och väljer Klistra in eller använder kortkommandot Skift+Insert (⌘+V på macOS).

Distribuera PARTS REST-webbtjänsten

  1. I Cloud Shell-fönstret kör du följande kommando för att klona lagringsplatsen som innehåller koden för den här övningen, inklusive PARTS REST-webbtjänsten:

    git clone https://github.com/microsoftdocs/mslearn-dotnetmaui-consume-rest-services
    
  2. Flytta till mappen Consume-REST-services :

    cd mslearn-dotnetmaui-consume-rest-services/src
    
  3. Kör följande kommando för att distribuera webbtjänsten Parts med sandbox-miljön i Azure Cloud Shell. Det här kommandot gör tjänsten tillgänglig via en unik URL. Anteckna den här URL:en när den visas. Du konfigurerar appen för att ansluta till webbtjänsten med hjälp av den här URL:en.

    bash initenvironment.sh
    

Granska koden för webbtjänsten

Kommentar

Du utför resten av den här övningen på din lokala utvecklingsdator.

  1. Öppna ett kommandotolksfönster på datorn och klona lagringsplatsen för den här övningen. Koden finns på lagringsplatsen net-maui-learn-consume-rest-services .

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

    Kommentar

    Det är bäst att klona eller ladda ned övningsinnehållet till en kort mappsökväg, till exempel C:\dev, för att undvika att bygggenererade filer överskrider den maximala sökvägens längd.

  2. Gå till mappen src\webservice\PartsServer i din klon av lagringsplatsen och öppna den PartsServer.sln lösningen med hjälp av Visual Studio eller mappen i Visual Studio Code. Den här lösningen innehåller en kopia av koden för webbtjänsten som du distribuerade till Azure i föregående procedur.

  3. I fönstret Solution Explorer expanderar du mappen Modeller . Den här mappen innehåller två filer:

    • Part.cs. Klassen Part representerar en del som tillhandahålls av REST-webbtjänsten. Fälten innehåller del-ID, delnamn, deltyp, tillgänglighetsdatum (när delen först angavs) och en lista över leverantörer. Egenskapen Href returnerar den relativa URI:n för delen. En REST-klient kan använda den här URI:n för att referera till den här specifika delen i REST-webbtjänsten. Egenskapen Leverantörer returnerar listan över leverantörer av delen som en sträng.

    • PartsFactory.cs. Klassen PartsFactory initierar listan över delar som tillhandahålls av tjänsten med hjälp av en liten uppsättning hårdkodade värden. I verkligheten skulle dessa data hämtas från en databas.

  4. I fönstret Solution Explorer expanderar du mappen Controllers . Den här mappen innehåller följande filer:

    • PartsController.cs. Klassen PartsController implementerar webb-API:et för tjänsten. Den innehåller metoder som gör det möjligt för ett klientprogram att hämta en lista över alla delar (Get), hitta information om en viss del med tanke på del-ID :t (den överbelastade versionen av Get), uppdatera informationen om en del (Put), lägga till en ny del i listan (Post) och ta bort en del från listan (Ta bort).

    • LoginController.cs. Klassen LoginController implementerar en enkel form av autentisering för webbtjänsten. En app måste skicka en HTTP GET-begäran till den här kontrollanten, som returnerar en auktoriseringstoken. Den här auktoriseringstoken används för att autentisera begäranden som skickas till PartsController.

    • BaseController.cs. Klassen BaseController innehåller den logik som används för att autentisera begäranden. Klassen PartsController ärver från den här klassen. Om klienten försöker anropa metoder i klassen PartsController utan att tillhandahålla en giltig autentiseringstoken returnerar metoderna ett HTTP 401-svar (obehörigt).

Granska koden för .NET MAUI-klientappen

Den här modulen använder .NET 8.0 SDK. Kontrollera att du har .NET 8.0 installerat genom att köra följande kommando i önskad kommandoterminal:

dotnet --list-sdks

Utdata som liknar följande exempel visas:

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

Kontrollera att en version som börjar med 8 visas. Om inget visas eller om kommandot inte hittas installerar du den senaste .NET 8.0 SDK:t.

  1. Stäng PartsServer-lösningen och öppna partsklientlösningen i mappen src\client\PartsClient på den klonade lagringsplatsen. Den här lösningen innehåller en partiell implementering av en .NET MAUI-klientapp som använder PartsServer-webbtjänsten .

  2. I fönstret Solution Explorer expanderar du mappen Data . Den här mappen innehåller koden för två klasser:

    • PartsManager.cs. Klassen PartsManager innehåller de metoder som klientappen använder för att interagera med REST-webbtjänsten. Den här klassen är för närvarande ofullständig. du lägger till nödvändig kod under den här övningen. När den är klar ansluter metoden GetClient till REST-webbtjänsten. Metoden GetAll returnerar en lista över delar från REST-webbtjänsten. Metoden Lägg till lägger till en ny del i listan över delar som hanteras av REST-webbtjänsten. Metoden Uppdatera ändrar information om en del som lagras av REST-webbtjänsten och metoden Ta bort tar bort en del.

    • Part.cs. Klassen Part modellerar en del som lagras i databasen. Den visar egenskaper som ett program kan använda för att komma åt fälten PartID, PartName, PartAvailableDate, PartType och PartSuppliers. Klassen innehåller också en verktygsmetod med namnet SupplierString som ett program kan använda för att hämta en formaterad sträng som innehåller leverantörsnamnen.

  3. I fönstret Solution Explorer expanderar du mappen Sidor . Den här mappen innehåller markering och kod för två sidor:

    • PartsPage.xaml. Den här sidan använder en CollectionView-layout med en DataTemplate för att visa information om de delar som är tillgängliga som en lista. DataTemplate använder databindning för att ansluta data som visas till de delar som hämtas från webbtjänsten. Du kan välja en rad i CollectionView för att redigera en del i AddPartPage, eller så kan du välja knappen Lägg till ny del för att lägga till en ny del.

    • AddPartPage.xaml. På den här sidan kan användarna ange och spara information för en ny del. Användare kan ange delnamnet, deltypen och en första leverantör. Del-ID:t och deltillgänglighetsdatumet genereras automatiskt.

  4. I fönstret Solution Explorer expanderar du mappen ViewModels . Den här mappen innehåller två klasser: AddPartViewModel.cs och PartsViewModel.cs. Det här är vymodellerna för respektive sidor och innehåller egenskaper och logik som sidan behöver för att visa och ändra data.

Logga in på tjänsten

REST-tjänsten kräver att du loggar in först för att hämta en auktoriseringstoken. Det finns ingen användarautentisering. Du anropar först en specifik slutpunkt för att hämta en auktoriseringstoken och skickar sedan tillbaka token till servern på varje efterföljande begäran i HTTP-huvudet.

  1. Öppna filen PartsManager.cs i mappen Data .

  2. Lägg till statiska fält för BaseAddress och URL enligt definitionen i följande kodfragment i klassen PartsManager . Ersätt text-URL :en GOES HERE med URL:en för REST-webbtjänsten som du antecknade tidigare:

    public class PartsManager
    {
        static readonly string BaseAddress = "URL GOES HERE";
        static readonly string Url = $"{BaseAddress}/api/";
        ...
    }
    
  3. Lägg till följande fält i klassen efter fältet Url . Det här fältet innehåller auktoriseringstoken som returneras när användaren loggar in:

    private static string authorizationKey;
    
  4. Hitta metoden GetClient. Den här metoden genererar för närvarande ett NotImplementedException-undantag . Ersätt den befintliga koden i den här metoden med följande kod. Den här koden skapar ett HttpClient-objekt och skickar sedan en begäran till inloggningsslutpunkten för REST-webbtjänsten. Tjänsten bör svara med ett meddelande som innehåller auktoriseringstoken. Deserialisera den här token och lägg till den som standardhuvud för auktoriseringsbegäran för efterföljande begäranden som skickas med hjälp av HttpClient-objektet :

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

Utför en GET-åtgärd för att hämta information för delar

  1. Leta redametoden GetAll i filen PartsManager.cs. Det här är en asynkron metod som returnerar en uppräkningsbar lista över delar. Den här metoden har ännu inte implementerats.

  2. I den här metoden tar du bort koden som genererar undantaget NotImplementedException .

  3. Kontrollera om enheten har internetanslutning med hjälp Connectivity av klassen . Om internet inte finns returnerar du en tom List<Part>.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return new List<Part>();
    
  4. Anropa metoden GetClient för att hämta ett HttpClient-objekt att arbeta med. Kom ihåg att GetClient är asynkront, så använd await-operatorn för att avbilda objektet som returneras av den här metoden.

  5. Anropa metoden GetStringAsync för HttpClient-objektet och ange bas-URL:en för att hämta en matris med delar från REST-webbtjänsten. Data returneras asynkront som en JSON-sträng.

  6. Deserialisera JSON-strängen som returneras av den här metoden till en lista över delobjekt med hjälp av metoden JsonSerializer.Deserialize. Returnera den här listan till anroparen.

    Den slutförda metoden bör se ut så här:

    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. Skapa och kör appen. När appen startar visas sidan Dellista och en lista över delar som hämtats med metoden GetAll ska visas. Följande bild visar appen som körs på Android:

    En skärmbild av appen Partsklient som körs på Android och som visar en lista över delar.

  8. När du är klar med databläddring stänger du appen och återgår till Visual Studio eller Visual Studio Code.

Utför en POST-åtgärd för att lägga till en ny del i databasen

  1. Leta upp metoden Lägg till i klassen PartsManager. Den här metoden har parametrar för delnamnet, en leverantör och deltypen. Metoden är asynkron. Metodens syfte är att infoga en ny del i databasen och returnera ett delobjekt som representerar det nyligen skapade objektet.

  2. Ta bort den befintliga koden i -metoden.

  3. Kontrollera om enheten har internetanslutning med hjälp Connectivity av klassen . Om internet inte finns returnerar du en tom Part.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return new Part();
    
  4. Skapa ett nytt delobjekt . Fyll i fälten med de data som skickas:

    • Ange fältet PartID till en tom sträng. Det här ID:t genereras av REST-webbtjänsten.
    • Skapa en ny lista som innehåller namnet på leverantören.
    • Ange fältet PartAvailableDate till DateTime.Now.
    • Hämta en HTTP-klient från metoden GetClient .
    var part = new Part()
    {
        PartName = partName,
        Suppliers = new List<string>(new[] { supplier }),
        PartID = string.Empty,
        PartType = partType,
        PartAvailableDate = DateTime.Now.Date
    };
    
  5. Anropa metoden GetClient för att hämta ett HttpClient-objekt att arbeta med.

  6. Skapa ett HttpRequestMessage objekt. Det här objektet används för att modellera den begäran som skickas till webbtjänsten. Initiera det med parametrar som anger vilket HTTP-verb som ska användas och URL:en för webbtjänsten att kommunicera med.

    var msg = new HttpRequestMessage(HttpMethod.Post, $"{Url}parts");
    
  7. Du måste skicka en nyttolast till webbtjänsten med den delinformation som ska skapas. Den här nyttolasten serialiseras till JSON. JSON-nyttolasten läggs till i HttpRequestMessage.Content egenskapen och serialiseras med JsonContent.Create -metoden.

    msg.Content = JsonContent.Create<Part>(part);
    
  8. Skicka nu meddelandet till webbtjänsten med HttpClient.SendAsync funktionen . Den funktionen returnerar ett HttpResponseMessage objekt som innehåller information om åtgärden på servern. Till exempel HTTP-svarskoder och information som skickas tillbaka från servern.

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

    Observera att ovanstående använder response.EnsureSuccessStatusCode metoden. Det utlöser ett fel om något annat än en 2xx HTTP-statuskod returneras.

  9. Om webbtjänsten returnerar information, till exempel ett objekt som serialiserats i JSON, kan du läsa det från HttpResponseMessage. Sedan kan du deserialisera JSON med hjälp av JsonSerializer.Deserialize.

    var returnedJson = await response.Content.ReadAsStringAsync();
    
    var insertedPart = JsonSerializer.Deserialize<Part>(returnedJson, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            });
    
  10. Returnera slutligen den nya infogade delen.

    return insertedPart;
    
  11. Skapa och kör appen. Välj knappen Lägg till ny del och ange ett namn, en typ och en leverantör för att skapa en ny del. Välj Spara. Metoden Lägg till i klassen PartsManager anropas, vilket skapar den nya delen i webbtjänsten. Om åtgärden lyckas visas sidan för dellistan igen med den nya delen längst ned i listan.

    En skärmbild av appen som körs efter att en ny del har lagts till. Den nya delen finns längst ned i listan.

  12. När du är klar med databläddring stänger du appen och återgår till Visual Studio eller Visual Studio Code.

Utför en PUT-åtgärd för att uppdatera informationen för en del i databasen

  1. Leta upp metoden Update i klassen PartsManager. Det här är en asynkron metod som tar ett delobjekt som parameter. Metoden har inget explicit returvärde. Returtypen är dock Aktivitet så att undantag returneras korrekt tillbaka till anroparen. Nu ska vi implementera PUT-funktionerna .

  2. Ta bort den befintliga koden.

  3. Precis som tidigare kontrollerar du om det finns en Internetanslutning.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return;
    
  4. Skapa en ny HttpRequestMessage, den här gången anger du en PUT-åtgärd och URL:en för uppdatering av delar.

    HttpRequestMessage msg = new(HttpMethod.Put, $"{Url}parts/{part.PartID}");
    
  5. Content Ange egenskapen för HttpRequestMessage med funktionen JsonContent.Create och den delparameter som skickades till funktionen.

    msg.Content = JsonContent.Create<Part>(part);
    
  6. Hämta en HTTP-klient från metoden GetClient .

    var client = await GetClient();
    
  7. Skicka begäran med HttpClient och kontrollera sedan att den lyckades.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    
  8. Skapa och kör appen. Välj en av delarna i listan. Sidan Lägg tilldel visas, den här gången med de egenskaper som redan är ifyllda. Uppdatera vad du vill.

  9. Välj Spara. Detta anropar metoden Uppdatera i klassen PartsManager för att skicka ändringarna till webbtjänsten. Om det lyckas visas ändringarna igen på sidan med en lista över delar.

    En skärmbild av appen som körs med det första objektet i listan uppdaterad.

    Kommentar

    Den del som du lade till i föregående uppgift visas inte på sidan Dellista . De data som appen använder återställs till en lista över fördefinierade delar varje gång appen körs. Detta är för att ge konsekvens för att testa appen.

Utför en DELETE-åtgärd för att ta bort information om en del från databasen

  1. Leta reda på metoden Ta bort i klassen PartsManager. Det här är en asynkron metod som tar en partId-sträng och returnerar en aktivitet.

  2. Ta bort den befintliga koden.

  3. Sök efter en internetanslutning.

    if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
        return;
    
  4. Skapa ett nytt HttpRequestMessage objekt. Ange först nu HTTP-verbet DELETE och URL:en för att ta bort en del.

    HttpRequestMessage msg = new(HttpMethod.Delete, $"{Url}parts/{partID}");
    
  5. Hämta en HTTP-klient från metoden GetClient .

    var client = await GetClient();
    
  6. Skicka begäran till webbtjänsten. Kontrollera om det har lyckats när det har returnerats.

    var response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode();
    
  7. Skapa och kör appen. Välj en del i listan och välj sedan Ta bortsidan Lägg till del . Om det lyckas visas sidan Dellista igen och den del som du har tagit bort visas inte längre.