Oktatóanyag: HTTP-kérések létrehozása .NET-konzolalkalmazásban c használatával #
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á történő 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.
- Konfigurálja a deszerializálást attribútumokkal.
Ha az oktatóanyag utolsó mintáját szeretné követni, letöltheti. A letöltési utasításokért lásd: Minták és oktatóanyagok.
Előfeltételek
- .NET SDK 6.0 vagy újabb
- Egy kódszerkesztő, például [Visual Studio Code (nyílt forráskódú, platformfüggetlen szerkesztő). A mintaalkalmazást Windows, Linux vagy macOS rendszeren, illetve Docker-tárolóban is futtathatja.
Az ügyfélalkalmazás létrehozása
Nyisson meg egy parancssort, és hozzon létre egy új könyvtárat az alkalmazáshoz. Legyen az aktuális könyvtár.
Adja meg a következő parancsot egy konzolablakban:
dotnet new console --name WebAPIClient
Ez a parancs létrehozza a kezdőfájlokat egy alapszintű ""Helló világ!" alkalmazás" alkalmazáshoz. A projekt neve "WebAPIClient".
Lépjen a "WebAPIClient" könyvtárba, és futtassa az alkalmazást.
cd WebAPIClient
dotnet run
dotnet run
automatikusan futdotnet restore
az alkalmazás által igényelt függőségek visszaállításához. Szükség esetén futdotnet build
is. Ekkor megjelenik az alkalmazás kimenete"Hello, World!"
. A terminálban nyomja le a CtrlCbillentyűkombinációt+ 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 projektekről a .NET Foundation esernyője alatt. A végpont a következő 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 A 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.cs
projektkönyvtárban, és cserélje le annak tartalmát a következőre:await ProcessRepositoriesAsync(); static async Task ProcessRepositoriesAsync(HttpClient client) { }
Ez a kód:
- A utasítást egy olyan hívásra
ProcessRepositoriesAsync
cseréliConsole.WriteLine
, amely a kulcsszótawait
használja. - Üres
ProcessRepositoriesAsync
metódust definiál.
- A utasítást egy olyan hívásra
Az osztályban az
Program
an HttpClient paranccsal kezelheti a kéréseket és a válaszokat úgy, hogy a tartalmat a következő C#-ra cseréli.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:
- A HTTP-fejlécek beállítása az összes kérelemhez:
- A
Accept
JSON-válaszok elfogadásához használt fejléc - Egy
User-Agent
fejléc. Ezeket a fejléceket a GitHub-kiszolgálókód ellenőrzi, és az adatok a GitHubról való lekéréséhez szükségesek.
- A
- A HTTP-fejlécek beállítása az összes kérelemhez:
A metódusban
ProcessRepositoriesAsync
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 rendszer a válasz törzsét adja vissza , Stringamely a feladat befejezésekor érhető el.
- A válaszsztringet
json
a rendszer a konzolra nyomtatja.
Hozza létre és futtassa az alkalmazást.
dotnet run
Nincs buildre vonatkozó figyelmeztetés, mert a
ProcessRepositoriesAsync
most tartalmaz egy operátortawait
. A kimenet a JSON-szöveg hosszú megjelenítése.
A JSON-eredmény deszerializálása
Az alábbi lépések C#-objektumokká alakítják át a JSON-választ. Az osztály használatával System.Text.Json.JsonSerializer deszerializálhatja a JSON-t 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 definiál egy osztályt, 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-értéke több tucat tulajdonságot tartalmaz, de csak a
name
tulajdonsá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.A C#-konvenció a tulajdonságnevek első betűjének nagybetűssé alakítása, de az
name
itt szereplő tulajdonság kisbetűvel kezdődik, mert ez pontosan megegyezik a JSON-ban szereplővel. Később megtudhatja, hogyan használhat olyan C# tulajdonságneveket, amelyek nem felelnek meg a JSON-tulajdonságneveknek.A szerializálóval C#-objektumokká alakíthatja a JSON-t. Cserélje le a metódus GetStringAsync(String) hívását
ProcessRepositoriesAsync
a következő sorokra:await using Stream stream = await client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos"); var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(stream);
A frissített kód helyébe a következő lép GetStringAsync(String)GetStreamAsync(String): . Ez a szerializáló metódus egy streamet használ sztring helyett forrásként.
Az első argumentum egy JsonSerializer.DeserializeAsync<TValue>(Stream, JsonSerializerOptions, CancellationToken)
await
kifejezés.await
A 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 másik két paraméter(JsonSerializerOptions
ésCancellationToken
) nem kötelező, és nem szerepel a kódrészletben.A
DeserializeAsync
metódus általános, ami azt jelenti, hogy típusargumentumokat ad meg, hogy milyen típusú objektumokat kell létrehozni a JSON-szövegből. Ebben a példában egyList<Repository>
másik általános objektumra, egy objektumra deszerializálódik.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 aRepository
rekord, mivel 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 a következő olvasott sorokat:
Console.Write(json);
a következő kóddal:
foreach (var repo in repositories ?? Enumerable.Empty<Repository>()) Console.Write(repo.name);
A fájl tetején a következő
using
irányelveknek kell szerepelnie:using System.Net.Http.Headers; using System.Text.Json;
Futtassa az alkalmazást.
dotnet run
A kimenet a .NET Foundation részét képező adattárak nevének listája.
Deszerializálás konfigurálása
A Repository.cs fájlban cserélje le a fájl tartalmát a következő C#-ra.
using System.Text.Json.Serialization; public record class Repository( [property: JsonPropertyName("name")] string Name);
Ez a kód:
- A tulajdonság nevét
name
a következőre módosítja:Name
. - Hozzáadja a JsonPropertyNameAttribute értéket annak megadásához, hogy ez a tulajdonság hogyan jelenik meg a JSON-ban.
- A tulajdonság nevét
A Program.cs fájlban frissítse a kódot a tulajdonság új nagybetűsítésének
Name
használatára:foreach (var repo in repositories) Console.Write(repo.Name);
Futtassa az alkalmazást.
A kimenet ugyanaz.
Kód újrabontása
A ProcessRepositoriesAsync
metódus elvégezheti az aszinkron munkát, és visszaadhatja az adattárak gyűjteményét. Módosítsa ezt a metódust a visszatéréshez Task<List<Repository>>
, és helyezze át az írott kódot a hívó közelében lévő konzolra.
Módosítsa az aláírást
ProcessRepositoriesAsync
egy olyan feladat visszaadásához, amelynek eredménye az objektumok listájaRepository
:static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)
Adja vissza az adattárakat a JSON-válasz feldolgozása után:
await using Stream stream = await client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos"); var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(stream); return repositories ?? new();
A fordító létrehozza a
Task<T>
visszatérési érték objektumát, mert ezt a metódust a következőként jelölte meg:async
.Módosítsa a Program.cs fájlt, és cserélje le a hívást
ProcessRepositoriesAsync
a következőre az eredmények rögzítéséhez, és írja be az egyes adattárak nevét a konzolra.var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) Console.Write(repo.Name);
Futtassa az alkalmazást.
A kimenet ugyanaz.
További tulajdonságok deszerializálása
Az alábbi lépésekben kódot ad hozzá a fogadott JSON-csomagban lévő tulajdonságok további feldolgozásához. Valószínűleg nem szeretne minden tulajdonságot feldolgozni, de néhány további hozzáadásával a C# egyéb funkcióit is bemutathatja.
Cserélje le az osztály tartalmát
Repository
a következőrecord
definícióra:using System.Text.Json.Serialization; public record class Repository( [property: JsonPropertyName("name")] string Name, [property: JsonPropertyName("description")] string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, [property: JsonPropertyName("homepage")] Uri Homepage, [property: JsonPropertyName("watchers")] int Watchers);
A Uri és
int
a típus beépített funkcióval rendelkezik, amelyet sztringre és sztringek ábrázolására lehet konvertálni. Nincs szükség további kódra a JSON-sztringformátumból a céltípusokba történő 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 jelez.Frissítse a
foreach
ciklust 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(); }
Futtassa 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 a JSON-válaszban így van formázva:
2016-02-08T21:27:00Z
Ez a formátum az egyezményes világidő (UTC) formátuma, ezért a deszerializálás eredménye egy DateTime olyan érték, amelynek Kind tulajdonsága .Utc
Ahhoz, hogy egy dátum és idő szerepeljen az időzónában, egyéni konverziós módszert kell írnia.
A Repository.cs fájlban adjon hozzá egy tulajdonságot a dátum és idő UTC-beli ábrázolásához, valamint egy olvasható
LastPush
tulajdonságot, amely a helyi időre 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( [property: JsonPropertyName("name")] string Name, [property: JsonPropertyName("description")] string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, [property: JsonPropertyName("homepage")] Uri Homepage, [property: JsonPropertyName("watchers")] int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc) { public DateTime LastPush => LastPushUtc.ToLocalTime(); }
A
LastPush
tulajdonság kifejezés testes tag használatával van definiálva aget
tartozékhoz. Nincsset
tartozék. A tartozék kihagyásávalset
egy írásvédett tulajdonságot definiálhat c# nyelven. (Igen, létrehozhat írásvédett tulajdonságokat C#-ban, de ezek értéke korlátozott.)Adjon hozzá egy másik kimeneti utasítást a Program.cs fájlban:
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.Text.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) { await using Stream stream = await client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos"); var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(stream); return repositories ?? new(); }
Futtassa 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üld, é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: JSON szerializálása és deszerializálása (marsall és nem házas) JSON a .NET-ben.