Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här handledningen bygger en app som skickar HTTP-begäranden till en REST-tjänst hos GitHub. Appen läser information i JSON-format och konverterar JSON till C#-objekt. Konvertering från JSON till C#-objekt kallas deserialisering.
Handledningen visar hur du:
- Skicka HTTP-begäranden.
- Deserialisera JSON-svar.
- Konfigurera deserialisering med attribut.
Om du föredrar att följa med i den sista för den här självstudien kan du ladda ned den. Instruktioner för nedladdning finns i Exempelfiler och Handledningar.
Förutsättningar
- Den senaste versionen av .NET SDK
- Visual Studio Code-redigerare
- C# DevKit
Skapa klientappen
- Öppna en kommandotolk och skapa en ny katalog för din app. Gör den till den aktuella katalogen. 
- Ange följande kommando i ett konsolfönster: - dotnet new console --name WebAPIClient- Det här kommandot skapar startfilerna för en grundläggande "Hello World"-app. Projektnamnet är "WebAPIClient". 
- Navigera till katalogen "WebAPIClient" och kör appen. - cd WebAPIClient- dotnet run- dotnet runkör automatiskt- dotnet restoreför att återställa eventuella beroenden som appen behöver. Den kör också- dotnet buildom det behövs. Du bör se appens resultat- "Hello, World!". I terminalen trycker du på Ctrl+C för att stoppa appen.
Att göra HTTP-förfrågningar
Den här appen anropar GitHub API- för att få information om projekten under .NET Foundation paraply. Slutpunkten är https://api.github.com/orgs/dotnet/repos. För att hämta information gör den en HTTP GET-begäran. Webbläsare gör också HTTP GET-begäranden så att du kan klistra in webbadressen i webbläsarens adressfält för att se vilken information du kommer att ta emot och bearbeta.
Använd klassen HttpClient för att göra HTTP-begäranden. HttpClient stöder endast asynkrona metoder för dess långvariga API:er. Följande steg skapar därför en asynkron metod och anropar den från main-metoden.
- Öppna filen - Program.csi projektkatalogen och ersätt dess innehåll med följande:- await ProcessRepositoriesAsync(); static async Task ProcessRepositoriesAsync(HttpClient client) { }- Den här koden: - Ersätter Console.WriteLine-instruktionen med ett anrop tillProcessRepositoriesAsyncsom använder nyckelordetawait.
- Definierar en tom ProcessRepositoriesAsync-metod.
 
- Ersätter 
- I klassen - Programanvänder du en HttpClient för att hantera begäranden och svar genom att ersätta innehållet med följande C#.- using System.Net.Http.Headers; using HttpClient client = new(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); await ProcessRepositoriesAsync(client); static async Task ProcessRepositoriesAsync(HttpClient client) { }- Den här koden: - Konfigurerar HTTP-huvuden för alla begäranden: - Ett Accept-huvud för att acceptera JSON-svar
- En User-Agentrubrik. Dessa huvuden kontrolleras av GitHub-serverkoden och är nödvändiga för att hämta information från GitHub.
 
- Ett 
 
- Konfigurerar HTTP-huvuden för alla begäranden: 
- I metoden - ProcessRepositoriesAsyncanropar du GitHub-slutpunkten som returnerar en lista över alla lagringsplatser under .NET Foundation-organisationen:- static async Task ProcessRepositoriesAsync(HttpClient client) { var json = await client.GetStringAsync( "https://api.github.com/orgs/dotnet/repos"); Console.Write(json); }- Den här koden: - Väntar på att uppgiften som returneras från att anropa HttpClient.GetStringAsync(String)-metoden. Den här metoden skickar en HTTP GET-begäran till den angivna URI:n. Svarets brödtext returneras som en String, som är tillgänglig när aktiviteten slutförs.
- Svarssträngen jsonskrivs ut till konsolen.
 
- Skapa appen och kör den. - dotnet run- Det finns ingen kompileringsvarning eftersom - ProcessRepositoriesAsyncnu innehåller en- awaitoperator. Utdata är en lång visning av JSON-text.
Deserialisera JSON-resultatet
Följande steg förenklar metoden för att hämta data och bearbeta dem. Du använder GetFromJsonAsync tilläggsmetoden som ingår i 📦 NuGet-paketet System.Net.Http.Json för att hämta och deserialisera JSON-resultaten till objekt.
- Skapa en fil med namnet Repository.cs och lägg till följande kod: - public record class Repository(string Name);- Föregående kod definierar en klass som representerar JSON-objektet som returneras från GitHub-API:et. Du använder den här klassen för att visa en lista över lagringsplatsnamn. - JSON för ett lagringsplatsobjekt innehåller dussintals egenskaper, men endast egenskapen - Namekommer att deserialiseras. Serialiseraren ignorerar automatiskt JSON-egenskaper för vilka det inte finns någon matchning i målklassen. Den här funktionen gör det enklare att skapa typer som endast fungerar med en delmängd fält i ett stort JSON-paket.- Även om den - GetFromJsonAsyncmetod som du använder i nästa punkt har en fördel av att vara skiftlägeskänslig när det gäller egenskapsnamn, är C#-konventionen att kapitalisera den första bokstaven med egenskapsnamn.
- HttpClientJsonExtensions.GetFromJsonAsync Använd metoden för att hämta och konvertera JSON till C#-objekt. Ersätt anropet till GetStringAsync(String) i metoden - ProcessRepositoriesAsyncmed följande rader:- var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos");- Den uppdaterade koden ersätter GetStringAsync(String) med HttpClientJsonExtensions.GetFromJsonAsync. - Det första argumentet för - GetFromJsonAsyncmetoden är ett- awaituttryck.- awaituttryck kan förekomma nästan var som helst i din kod, även om du hittills bara har sett dem som en del av en tilldelningssats. Nästa parameter- requestUriär valfri och behöver inte anges om den redan angavs när objektet skapades- client. Du har inte angett objektet- clientmed den URI som begäran ska skickas till, så du har angett URI:n nu. Den sista valfria parametern utelämnas- CancellationTokeni kodfragmentet.- Metoden - GetFromJsonAsyncär allmän, vilket innebär att du anger typargument för vilken typ av objekt som ska skapas från den hämtade JSON-texten. I det här exemplet deserialiserar du till en- List<Repository>, som är ett annat allmänt objekt, en System.Collections.Generic.List<T>. Klassen- List<T>lagrar en samling objekt. Typargumentet deklarerar typen av objekt som lagras i- List<T>. Typargumentet är din- Repositorypost eftersom JSON-texten representerar en samling lagringsplatsobjekt.
- Lägg till kod för att visa namnet på varje lagringsplats. Ersätt raderna som lyder: - Console.Write(json);- med följande kod: - foreach (var repo in repositories ?? Enumerable.Empty<Repository>()) Console.WriteLine(repo.Name);
- Följande - usingdirektiv bör finnas överst i filen:- using System.Net.Http.Headers; using System.Net.Http.Json;
- Kör appen. - dotnet run- Utdata är en lista över namnen på de lagringsplatser som ingår i .NET Foundation. 
Omstrukturera koden
Metoden ProcessRepositoriesAsync kan utföra asynkront arbete och returnera en samling lagringsplatser. Ändra den metoden så att den returnerar Task<List<Repository>>, och flytta koden som skriver till konsolen nära dess anropare.
- Ändra signaturen för - ProcessRepositoriesAsyncför att returnera en uppgift vars resultat är en lista över- Repositoryobjekt:- static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)
- Returnera lagringsplatserna efter bearbetning av JSON-svaret: - var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new();- Kompilatorn genererar - Task<T>-objektet för returvärdet eftersom du har markerat den här metoden som- async.
- Ändra Program.cs-filen och ersätt anropet till - ProcessRepositoriesAsyncmed följande för att samla in resultaten och skriva varje lagringsplatsnamn till konsolen.- var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) Console.WriteLine(repo.Name);
- Kör appen. - Resultatet är detsamma. 
Deserialisera fler egenskaper
I följande steg utökar vi koden för att bearbeta fler egenskaper från JSON-nyttolasten som returneras av GitHub-API:et. Du behöver förmodligen inte bearbeta alla egenskaper, men om du lägger till några exempel visas ytterligare C#-funktioner.
- Ersätt innehållet i - Repositoryklassen med följande- recorddefinition. Importera- System.Text.Json.Serializationnamnområdet och använd- [JsonPropertyName]attributet för att mappa JSON-fält till C#-egenskaper explicit.- using System.Text.Json.Serialization; public record class Repository( string Name, string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, Uri Homepage, int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc );- Typerna Uri och - inthar inbyggda funktioner för att konvertera till och från strängrepresentation. Ingen extra kod behövs för att deserialisera från JSON-strängformat till dessa måltyper. Om JSON-paketet innehåller data som inte konverteras till en måltyp utlöser serialiseringsåtgärden ett undantag.- JSON använder - lowercaseofta eller- snake_caseför egenskapsnamn. Fält som- html_urloch- pushed_atföljer inte namngivningskonventionerna för C# PascalCase. Genom att använda- [JsonPropertyName]ser du till att dessa JSON-nycklar är korrekt bundna till motsvarande C#-egenskaper, även om deras namn skiljer sig åt om eller innehåller understreck. Den här metoden garanterar förutsägbar och stabil deserialisering samtidigt som egenskapsnamn för PascalCase tillåts i C#. Dessutom är- GetFromJsonAsync-metoden- case-insensitivevid matchning av egenskapsnamn, så ingen ytterligare konvertering krävs.
- Uppdatera - foreach-loopen i filen Program.cs för att visa egenskapsvärdena:- foreach (var repo in repositories) { Console.WriteLine($"Name: {repo.Name}"); Console.WriteLine($"Homepage: {repo.Homepage}"); Console.WriteLine($"GitHub: {repo.GitHubHomeUrl}"); Console.WriteLine($"Description: {repo.Description}"); Console.WriteLine($"Watchers: {repo.Watchers:#,0}"); Console.WriteLine(); }
- Kör appen. - Listan innehåller nu de ytterligare egenskaperna. 
Lägg till en datumegenskap
Datumet för den senaste push-åtgärden formateras på det här sättet i JSON-svaret:
2016-02-08T21:27:00Z
Det här formatet är för Coordinated Universal Time (UTC), så resultatet av deserialisering är ett DateTime värde vars Kind egenskap är Utc.
För att få ett datum och en tid representerad i tidszonen måste du skriva en anpassad konverteringsmetod.
- I Repository.cslägger du till en egenskap för UTC-representationen av datum och tid och en skrivskyddad - LastPushegenskap som returnerar datumet konverterat till lokal tid, och filen bör se ut så här:- using System.Text.Json.Serialization; public record class Repository( string Name, string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, Uri Homepage, int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc ) { public DateTime LastPush => LastPushUtc.ToLocalTime(); }- Egenskapen - LastPushdefinieras med hjälp av en uttrycksbaserad medlem för- get-accessorn. Det finns ingen- setaccessor. Att utelämna- set-accessorn är ett sätt att definiera en skrivskyddad egenskap i C#. (Ja, du kan skapa skrivskyddade egenskaper i C#, men deras värde är begränsat.)
- Lägg till ytterligare en utdatasats i Program.cs: igen: - Console.WriteLine($"Last push: {repo.LastPush}");
- Den fullständiga appen bör likna följande Program.cs fil: - using System.Net.Http.Headers; using System.Net.Http.Json; using HttpClient client = new(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) { Console.WriteLine($"Name: {repo.Name}"); Console.WriteLine($"Homepage: {repo.Homepage}"); Console.WriteLine($"GitHub: {repo.GitHubHomeUrl}"); Console.WriteLine($"Description: {repo.Description}"); Console.WriteLine($"Watchers: {repo.Watchers:#,0}"); Console.WriteLine($"{repo.LastPush}"); Console.WriteLine(); } static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client) { var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new List<Repository>(); }
- Kör appen. - Utdata innehåller datum och tid för den senaste push-överföringen till varje lagringsplats. 
Nästa steg
I den här självstudien skapade du en app som gör webbbegäranden och parsar resultatet. Din version av appen ska nu matcha det färdiga exemplet.
Läs mer om hur du konfigurerar JSON-serialisering i Så här serialiserar och deserialiserar du (seriell och deseriell) JSON i .NET.