Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez az oktatóanyag létrehoz egy alkalmazást, amely HTTP-kéréseket ad ki egy REST-szolgáltatásnak a GitHubon. Az alkalmazás JSON formátumban olvassa be az információkat, és C#-objektumokká alakítja a JSON-t. A JSON-ból C#-objektumokká való konvertálást deszerializálásnak nevezzük.
Az oktatóanyag bemutatja, hogyan:
- HTTP-kérések küldése.
- JSON-válaszok deszerializálása.
- Deszerializálás konfigurálása attribútumokkal.
Ha az oktatóanyag utolsó mintáját szeretné követni, letöltheti. A letöltési utasításokért tekintse meg példákat és oktatóanyagokat.
Előfeltételek
- A legújabb .NET SDK
- Visual Studio Code szerkesztő
- A C# DevKit
Az ügyfélalkalmazás létrehozása
Nyisson meg egy parancssort, és hozzon létre egy új könyvtárat az alkalmazáshoz. Állítsa be az aktuális könyvtárat.
Adja meg a következő parancsot egy konzolablakban:
dotnet new console --name WebAPIClientEz a parancs létrehozza a kezdőfájlokat egy alapszintű "Hello World" alkalmazáshoz. A projekt neve "WebAPIClient".
Lépjen a "WebAPIClient" könyvtárba, és futtassa az alkalmazást.
cd WebAPIClientdotnet rundotnet runautomatikusan futtatjadotnet restoreaz alkalmazás által igényelt függőségek helyreállításához.dotnet buildis fut, ha szükséges. Látnia kell az alkalmazás kimenetét"Hello, World!". A terminálban nyomja le a CtrlC+ az alkalmazás leállításához.
HTTP-kérések létrehozása
Ez az alkalmazás meghívja a GitHub API-t , hogy információkat kapjon a .NET Foundation esernyője alatti projektekről. A végpont az https://api.github.com/orgs/dotnet/repos. Az információk lekéréséhez HTTP GET kérést küld. A böngészők HTTP GET kéréseket is intéznek, így beillesztheti ezt az URL-címet a böngésző címsorába, hogy lássa, milyen adatokat fog kapni és feldolgozni.
HttpClient Az osztály használatával HTTP-kéréseket kezdeményezhet. HttpClient csak aszinkron metódusokat támogat a hosszú ideig futó API-khoz. Az alábbi lépések tehát létrehoznak egy aszinkron metódust, és meghívják a Main metódusból.
Nyissa meg a fájlt a
Program.csprojektkönyvtárban, és cserélje le a tartalmát a következőre:await ProcessRepositoriesAsync(); static async Task ProcessRepositoriesAsync(HttpClient client) { }Ez a kód:
- Az utasítást egy olyan hívásra
Console.WriteLinecseréliProcessRepositoriesAsync, amely a kulcsszótawaithasználja. - Üres
ProcessRepositoriesAsyncmetódust definiál.
- Az utasítást egy olyan hívásra
Az
Programosztályban használjon HttpClient egy metódust a kérések és válaszok kezelésére, a következő C#-kódra cserélve a tartalmat.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) { }Ez a kód:
- HTTP-fejlécek beállítása az összes kéréshez:
- Fejléc
AcceptjSON-válaszok elfogadásához - Egy
User-Agentfejléc. Ezeket a fejléceket a GitHub-kiszolgálókód ellenőrzi, és az adatok GitHubról való lekéréséhez szükségesek.
- Fejléc
- HTTP-fejlécek beállítása az összes kéréshez:
ProcessRepositoriesAsyncA metódusban hívja meg a GitHub-végpontot, amely a .NET-alapszervezet összes adattárának listáját adja vissza:static async Task ProcessRepositoriesAsync(HttpClient client) { var json = await client.GetStringAsync( "https://api.github.com/orgs/dotnet/repos"); Console.Write(json); }Ez a kód:
- Várja a hívási HttpClient.GetStringAsync(String) metódusból visszaadott feladatot. Ez a metódus HTTP GET kérést küld a megadott URI-nak. A válasz tartalmát String formájában adjuk vissza, amely a feladat befejezésekor érhető el.
- A válaszsztring
jsonki lesz írva a konzolra.
Hozza létre és futtassa az alkalmazást.
dotnet runNincs összeállítási figyelmeztetés, mert a
ProcessRepositoriesAsyncmost tartalmaz egyawaitoperátort. A kimenet a JSON-szöveg hosszú megjelenítése.
A JSON-eredmény deszerializálása
Az alábbi lépések leegyszerűsítik az adatok beolvasásának és feldolgozásának megközelítését. A GetFromJsonAsync bővítménymetódus használatával 📦 beolvassa és deszerializálja a JSON-eredményeket objektumokká.
Hozzon létre egy Repository.cs nevű fájlt, és adja hozzá a következő kódot:
public record class Repository(string Name);Az előző kód egy osztályt határoz meg, amely a GitHub API-ból visszaadott JSON-objektumot jelöli. Ezzel az osztálysal megjelenítheti az adattárnevek listáját.
Az adattárobjektum JSON-ja több tucat tulajdonságot tartalmaz, de csak a
Nametulajdonság lesz deszerializálva. A szerializáló automatikusan figyelmen kívül hagyja azokat a JSON-tulajdonságokat, amelyek esetében nincs egyezés a célosztályban. Ez a funkció megkönnyíti az olyan típusok létrehozását, amelyek csak a mezők egy részhalmazával működnek egy nagy JSON-csomagban.Bár a
GetFromJsonAsynckövetkező pontban használt módszer előnye, hogy a kis- és nagybetűk nem érzékenek a tulajdonságnevekhez, a C#-konvenció a tulajdonságnevek első betűjének nagybetűssé ciója.A metódus használatával HttpClientJsonExtensions.GetFromJsonAsync beolvassa és C#-objektumokká konvertálja a JSON-t. Cserélje le a GetStringAsync(String) metódusban a
ProcessRepositoriesAsynchívást az alábbi sorokra:var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos");A frissített kód a GetStringAsync(String)-t lecseréli HttpClientJsonExtensions.GetFromJsonAsync-re.
A metódus első argumentuma
GetFromJsonAsyncegyawaitkifejezés.awaita kifejezések szinte bárhol megjelenhetnek a kódban, bár eddig csak egy hozzárendelési utasítás részeként látta őket. A következő paraméter nem kötelező,requestUriés nem kell megadni, ha már meg lett adva azclientobjektum létrehozásakor. Nem adta meg azclientobjektumnak a kérés küldéséhez szükséges URI-t, ezért most adta meg az URI-t. Az utolsó választható paraméter, aCancellationTokenkódrészlet kihagyva.A
GetFromJsonAsyncmetódus általános, ami azt jelenti, hogy típusargumentumokat ad meg ahhoz, hogy milyen típusú objektumokat kell létrehozni a beolvasott JSON-szövegből. Ebben a példában egyList<Repository>típusú objektumot deszerializálsz, ami egy másik általános objektum, egy System.Collections.Generic.List<T>. AzList<T>osztály objektumgyűjteményt tárol. A típusargumentum deklarálja a fájlbanList<T>tárolt objektumok típusát. A típusargumentum aRepositoryrekord, mert a JSON-szöveg adattárobjektumok gyűjteményét jelöli.Adjon hozzá kódot az egyes adattárak nevének megjelenítéséhez. Cserélje le azokat a sorokat, amelyek így szólnak:
Console.Write(json);a következő kóddal:
foreach (var repo in repositories ?? Enumerable.Empty<Repository>()) Console.WriteLine(repo.Name);A fájl tetején a következő
usingirányelveknek kell szerepelnie:using System.Net.Http.Headers; using System.Net.Http.Json;Indítsa el az alkalmazást.
dotnet runA kimenet a .NET Foundation részét képező adattárak nevének listája.
A kód újrabontása
A ProcessRepositoriesAsync metódus képes elvégezni az aszinkron munkát, és visszaadni az adattárak gyűjteményét. Módosítsa ezt a metódust úgy, hogy Task<List<Repository>> értéket adjon vissza, és helyezze át a konzolra író kódot a hívó közelébe.
Módosítsa a
ProcessRepositoriesAsyncaláírását úgy, hogy egy feladatot adjon vissza, amelynek eredménye egyRepositoryobjektumokból álló lista.static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)A JSON-válasz feldolgozása után adja vissza az adattárakat:
var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new();A fordító létrehozza az
Task<T>objektumot a visszatérési értékhez, mert ezt a metódustasync-ként jelölte meg.Módosítsa a Program.cs fájlt, és cserélje le a hívást
ProcessRepositoriesAsynca következőre az eredmények rögzítéséhez és az egyes adattárak nevének a konzolra való írásához.var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) Console.WriteLine(repo.Name);Indítsa el az alkalmazást.
A kimenet ugyanaz.
További tulajdonságok deszerializálása
Az alábbi lépésekben kiterjesztjük a kódot, hogy a GitHub API által visszaadott JSON hasznos adatokból további tulajdonságokat dolgozzanak fel. Valószínűleg nem kell minden tulajdonságot feldolgoznia, de néhány további C#-funkciót is bemutat.
Cserélje le az
Repositoryosztály tartalmát a következőrecorddefinícióra. Ügyeljen arra, hogy importálja aSystem.Text.Json.Serializationnévteret, és alkalmazza az attribútumot a[JsonPropertyName]JSON-mezők C#-tulajdonságokra való leképezéséhez.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 );A Uri típusok beépített funkcióval rendelkeznek a string reprezentációvá való átalakításhoz és visszaalakításhoz. Nincs szükség további kódra a JSON-sztringformátumból a céltípusokra való deszerializáláshoz. Ha a JSON-csomag olyan adatokat tartalmaz, amelyek nem konvertálhatók céltípusra, a szerializálási művelet kivételt eredményez.
A JSON gyakran használ
lowercasevagysnake_casetulajdonságneveket. Olyan mezők, minthtml_urléspushed_at, nem követik a PascalCase elnevezési konvencióit a C#-ban.[JsonPropertyName]használata biztosítja, hogy ezek a JSON-kulcsok helyesen legyenek kötve a megfelelő C#-tulajdonságaikhoz, még akkor is, ha a nevük különböző esetű vagy aláhúzásokat tartalmaz. Ez a megközelítés kiszámítható és stabil deszerializálást biztosít, miközben engedélyezi a PascalCase tulajdonságneveket a C#-ban. Emellett aGetFromJsonAsyncmetóduscase-insensitivea tulajdonságnevek összehasonlításánál, így nincs szükség további átalakításra.Frissítse a
foreachciklust a Program.cs fájlban a tulajdonságértékek megjelenítéséhez: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(); }Indítsa el az alkalmazást.
A lista most már tartalmazza a további tulajdonságokat.
Dátumtulajdonság hozzáadása
Az utolsó leküldéses művelet dátuma így van formázva a JSON-válaszban:
2016-02-08T21:27:00Z
Ez a formátum az egyezményes világidő (UTC) formátuma, így a deszerializálás eredménye olyan DateTime érték, amelynek Kind tulajdonsága a Utc.
Ha az időzónában meg szeretné jeleníteni a dátumot és az időt, egyéni konverziós módszert kell írnia.
A Repository.cs adjon hozzá egy tulajdonságot a dátum és az idő UTC-ábrázolásához, valamint egy olvasható
LastPushtulajdonságot, amely a helyi idővé konvertált dátumot adja vissza, a fájlnak a következőhöz hasonlóan kell kinéznie: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(); }A
LastPushtulajdonságot a tartozék számára kifejezés-alapú tag használatával definiálják. Nincssettartozék. Asethozzáférő kihagyása egy írásvédett tulajdonságot definiál a C#-ban. (Igen, írásvédett tulajdonságokat is létrehozhat a C#-ban, de értékük korlátozott.)Adjon hozzá egy másik kimeneti utasítást a Program.cs: ismét:
Console.WriteLine($"Last push: {repo.LastPush}");A teljes alkalmazásnak a következő Program.cs fájlhoz kell hasonlítania:
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>(); }Indítsa el az alkalmazást.
A kimenet tartalmazza az egyes adattárakba való utolsó leküldés dátumát és időpontját.
Következő lépések
Ebben az oktatóanyagban létrehozott egy alkalmazást, amely webes kéréseket készít, és elemzi az eredményeket. Az alkalmazás verziójának most már meg kell egyeznie a kész mintával.
További információ a JSON szerializálás konfigurálásáról a JSON szerializálásának és deszerializálásának (marshal és unmarshal) a .NET-ben való konfigurálásáról.