Megosztás a következőn keresztül:


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

  1. Nyisson meg egy parancssort, és hozzon létre egy új könyvtárat az alkalmazáshoz. Legyen az aktuális könyvtár.

  2. 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".

  3. Lépjen a "WebAPIClient" könyvtárba, és futtassa az alkalmazást.

    cd WebAPIClient
    
    dotnet run
    

    dotnet run automatikusan fut dotnet restore az alkalmazás által igényelt függőségek visszaállításához. Szükség esetén fut dotnet 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.

  1. 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ót await használja.
    • Üres ProcessRepositoriesAsync metódust definiál.
  2. 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.
  3. 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.
  4. Hozza létre és futtassa az alkalmazást.

    dotnet run
    

    Nincs buildre vonatkozó figyelmeztetés, mert a ProcessRepositoriesAsync most tartalmaz egy operátort await . 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á.

  1. 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.

  2. 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 és CancellationToken) 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 egy List<Repository>másik általános objektumra, egy objektumra deszerializálódik.System.Collections.Generic.List<T> Az List<T> osztály objektumgyűjteményt tárol. A típusargumentum deklarálja a fájlban List<T>tárolt objektumok típusát. A típusargumentum a Repository rekord, mivel a JSON-szöveg adattárobjektumok gyűjteményét jelöli.

  3. 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);
    
  4. A fájl tetején a következő using irányelveknek kell szerepelnie:

    using System.Net.Http.Headers;
    using System.Text.Json;
    
  5. 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

  1. 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.
  2. 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);
    
  3. 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.

  1. Módosítsa az aláírást ProcessRepositoriesAsync egy olyan feladat visszaadásához, amelynek eredménye az objektumok listája Repository :

    static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)
    
  2. 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.

  3. 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);
    
  4. 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.

  1. 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.

  2. 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();
    }
    
  3. 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.

  1. 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 a get tartozékhoz. Nincs set tartozék. A tartozék kihagyásával set 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.)

  2. Adjon hozzá egy másik kimeneti utasítást a Program.cs fájlban:

    Console.WriteLine($"Last push: {repo.LastPush}");
    
  3. 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();
    }
    
  4. 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.