Öğretici: C kullanarak bir .NET konsol uygulamasında HTTP istekleri yapma#

Bu öğreticide, bir rest hizmetine http istekleri GitHub. Uygulama bilgileri JSON biçiminde okur ve JSON'u C# nesnelerine dönüştürür. JSON'dan C# nesnelerine dönüştürme, ' deserialization olarak bilinir.

Öğreticide şunların nasıl olduğu gösterir:

  • HTTP istekleri gönderme.
  • JSON yanıtlarını deserialize.
  • Özniteliklerle deserialization'i yapılandırma.

Bu öğreticinin son örneğini takip etmek isterseniz indirebilirsiniz. İndirme yönergeleri için bkz. Örnekler ve Öğreticiler.

Önkoşullar

İstemci uygulamasını oluşturma

  1. Bir komut istemi açın ve uygulama için yeni bir dizin oluşturun. Bunu geçerli dizine göre seçin.

  2. Konsol penceresine aşağıdaki komutu girin:

    dotnet new console --name WebAPIClient
    

    Bu komut, temel bir "Merhaba Dünya" uygulaması için başlangıç dosyalarını oluşturur. Proje adı "WebAPIClient" şeklindedir.

  3. "WebAPIClient" dizinine gidin ve uygulamayı çalıştırın.

    cd WebAPIClient
    
    dotnet run
    

    dotnet run , dotnet restore uygulamanın ihtiyacı olan bağımlılıkları geri yüklemek için otomatik olarak çalışır. Ayrıca gerekirse dotnet build çalışır.

HTTP isteğinde bulunma

Bu uygulama, .NET Foundation GitHub projeler hakkında bilgi almak için GitHub API'sini çağırıyor. Uç nokta: https://api.github.com/orgs/dotnet/repos . Bilgileri almak için bir HTTP GET isteği yapar. Tarayıcılar ayrıca HTTP GET istekleri de göndererek bu URL'yi tarayıcı adres çubuğuna yapıştırarak hangi bilgileri alasınız ve işleyebilirsiniz.

HTTP HttpClient istekleri yapmak için sınıfını kullanın. HttpClient yalnızca uzun süre çalışan API'leri için zaman uyumsuz yöntemleri destekler. Bu nedenle aşağıdaki adımlarda zaman uyumsuz bir yöntem oluşturularak Main yönteminden çağrılabilirsiniz.

  1. Proje Program.cs dizininize dosyasını açın ve sınıfına aşağıdaki zaman uyumsuz yöntemi Program ekleyin:

    private static async Task ProcessRepositories()
    {
    }
    
  2. usingC# derleyicisi türü tanımak için Program.cs dosyasının en üstüne bir yönerge Task ekleyin:

    using System.Threading.Tasks;
    

    Bu noktada çalıştırırsanız, derleme başarılı olur, ancak bu yöntemin herhangi bir işleç içermesi konusunda uyararak zaman dotnet build await uyumlu olarak çalışır. Daha sonra yöntemini await doldururken işleçler eksersiniz.

  3. Main yöntemini aşağıdaki kod ile değiştirin:

    static async Task Main(string[] args)
    {
        await ProcessRepositories();
    }
    

    Bu kod:

    • değiştiricisini ekleyerek Main ve dönüş türünü olarak async değiştirerek imzasını Task değiştirir.
    • deyimini Console.WriteLine anahtar sözcüğünü kullanan ProcessRepositories çağrısıyla await değiştirir.
  4. sınıfında, Program istekleri ve yanıtları işlemek için statik bir örneği HttpClient oluşturun.

    namespace WebAPIClient
    {
        class Program
        {
            private static readonly HttpClient client = new HttpClient();
    
            static async Task Main(string[] args)
            {
                //...
            }
        }
    }
    
  5. ProcessRepositoriesyönteminde, .NET GitHub altındaki tüm depoların listesini döndüren bir uç noktayı çağırabilirsiniz:

    private static async Task ProcessRepositories()
    {
        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 stringTask = client.GetStringAsync("https://api.github.com/orgs/dotnet/repos");
    
        var msg = await stringTask;
        Console.Write(msg);
    }
    

    Bu kod:

    • Tüm istekler için HTTP üst bilgilerini ayarlar:
      • AcceptJSON yanıtlarını kabul etmek için üst bilgi
      • Üst User-Agent bilgi. Bu üst bilgiler, sunucu GitHub tarafından denetlenir ve bu üst bilgilerden bilgi almak GitHub.
    • Web HttpClient.GetStringAsync(String) isteği yapmak ve yanıtı almak için çağrıları. Bu yöntem, web isteğini yapan bir görev başlatır. İstek döndür geldiğinde, görev yanıt akışını okur ve akışın içeriğini ayıklar. Yanıtın gövdesi, görev tamamlandığında String kullanılabilen bir olarak döndürülür.
    • Yanıt dizesi için görevi bekler ve yanıtı konsola yazdırır.
  6. Dosyanın using en üstüne iki yönerge ekleyin:

    using System.Net.Http;
    using System.Net.Http.Headers;
    
  7. Uygulamayı derleme ve çalıştırma.

    dotnet run
    

    Artık bir işleç içerdiği için ProcessRepositories derleme uyarısı await yoktur.

    Çıktı, JSON metninin uzun bir görüntüsü.

JSON Sonucu'unrialize'sı

Aşağıdaki adımlar JSON yanıtını C# nesnelerine dönüştürür. System.Text.Json.JsonSerializerJSON'u nesnelere serisini desrialize etmek için sınıfını kullanırsiniz.

  1. repo.cs adlı bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    using System;
    
    namespace WebAPIClient
    {
        public class Repository
        {
            public string name { get; set; }
        }
    }
    

    Yukarıdaki kod, GitHub API'sinde döndürülen JSON nesnesini temsil GitHub tanımlar. Bu sınıfı kullanarak depo adlarının listesini görüntüleyebilirsiniz.

    Bir depo nesnesi için JSON onlarca özellik içerir, ancak yalnızca name özelliğinrialized. Seri hale getirici, hedef sınıfta eşleşmenin olduğu JSON özelliklerini otomatik olarak yok sayar. Bu özellik, büyük bir JSON paketinde alanların yalnızca bir alt kümesiyle çalışacak türler oluşturmanızı kolaylaştırır.

    C# kuralı, özellik adlarının ilk harfini büyük harfle yapmaktır, ancak buradaki özellik JSON'dakiyle tam olarak eşleştirilene kadar küçük name harfle başlar. Daha sonra, JSON özellik adları ile eşleşmeyan C# özellik adlarının nasıl kullanacağız?

  2. JSON'u C# nesnelerine dönüştürmek için seri hale getiriciyi kullanın. yönteminde çağrısı GetStringAsync(String) aşağıdaki ProcessRepositories satırlarla değiştirin:

    var streamTask = client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos");
    var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(await streamTask);
    

    Güncelleştirilmiş kod ile GetStringAsync(String) GetStreamAsync(String) değiştirilir. Bu seri hale getirici yöntemi, kaynağı olarak dize yerine bir akış kullanır.

    için ilk bağımsız değişken JsonSerializer.DeserializeAsync<TValue>(Stream, JsonSerializerOptions, CancellationToken) bir await ifadedir. await ifadeleri, şu an için yalnızca atama deyiminin bir parçası olarak görse bile neredeyse kodunuzun herhangi bir yerinde görünebilir. Diğer iki parametre olan JsonSerializerOptions ve CancellationToken , isteğe bağlıdır ve kod parçacığında atlanır.

    yöntemi DeserializeAsync geneldir,yani JSON metninden ne tür nesneler oluşturulacak için tür bağımsız değişkenleri sağlar. Bu örnekte, başka bir genel nesne olan List<Repository> bir olan bir için seri durumdan seri durumdan. System.Collections.Generic.List<T> sınıfı List<T> bir nesne koleksiyonunu depolar. tür bağımsız değişkeni içinde depolanan nesnelerin türünü List<T> bildirer. JSON metni depo nesneleri koleksiyonunu temsil ettiği Repository için tür bağımsız değişkeni sınıfınızdır.

  3. Her deponun adını görüntülemek için kod ekleyin. Şu satırları değiştirin:

    var msg = await stringTask;
    Console.Write(msg);
    

    aşağıdaki kodla:

    foreach (var repo in repositories)
        Console.WriteLine(repo.name);
    
  4. Dosyanın using en üstüne aşağıdaki yönergeleri ekleyin:

    using System.Collections.Generic;
    using System.Text.Json;
    
  5. Uygulamayı çalıştırın.

    dotnet run
    

    Çıktı, .NET Foundation'ın parçası olan depoların adlarının listesidir.

Deserialization'i yapılandırma

  1. repo.cs içinde, özelliğini olarak değiştirerek ve bu özelliğin name Name [JsonPropertyName] JSON'da nasıl görüntülendiğinden belirtmek için bir öznitelik ekleyin.

    [JsonPropertyName("name")]
    public string Name { get; set; }
    
  2. Ad alanını System.Text.Json.Serialization using yönergelerine ekleyin:

    using System.Text.Json.Serialization;
    
  3. Program.cs içinde, özelliğinin yeni büyük/büyük harf kullanımını kullanmak için kodu Name güncelleştirin:

    Console.WriteLine(repo.Name);
    
  4. Uygulamayı çalıştırın.

    Çıkış aynıdır.

Kodu yeniden düzenleme

yöntemi ProcessRepositories zaman uyumsuz işi yapar ve depoların bir koleksiyonunu geri yükleyebilir. Bu yöntemi, 'i List<Repository> iade etmek ve bilgileri yönteme yazan kodu taşımak için Main değiştirir.

  1. sonucu bir nesne ProcessRepositories listesi olan bir görevi geri dönmek için imzasını Repository değiştirme:

    private static async Task<List<Repository>> ProcessRepositories()
    
  2. JSON yanıtını işledikten sonra depoları geri dönüş:

    var streamTask = client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos");
    var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(await streamTask);
    return repositories;
    

    Bu yöntemi olarak Task<T> işaretleyebilirsiniz çünkü derleyici dönüş değeri için nesnesini async oluşturur.

  3. Sonuçları Main yakalamak ve her depo adını konsola yazmak için yöntemini değiştirme. MainYöntemi şu şekilde görünür:

    public static async Task Main(string[] args)
    {
        var repositories = await ProcessRepositories();
    
        foreach (var repo in repositories)
            Console.WriteLine(repo.Name);
    }
    
  4. Uygulamayı çalıştırın.

    Çıkış aynı.

Daha fazla özellik serisini kaldırma

Aşağıdaki adımlar, alınan JSON paketindeki özelliklerden daha fazlasını işlemek için kod ekler. Büyük olasılıkla her özelliği işlemek istemezsiniz, ancak birkaç ek eklemek C# ' nin diğer özelliklerini gösterir.

  1. Aşağıdaki özellikleri Repository sınıf tanımına ekleyin:

    [JsonPropertyName("description")]
    public string Description { get; set; }
    
    [JsonPropertyName("html_url")]
    public Uri GitHubHomeUrl { get; set; }
    
    [JsonPropertyName("homepage")]
    public Uri Homepage { get; set; }
    
    [JsonPropertyName("watchers")]
    public int Watchers { get; set; }
    

    UriVe int türleri, dize gösterimine ve dizeden dönüştürme için yerleşik işlevlere sahiptir. JSON dize biçiminden bu hedef türlerine seri durumdan çıkarmak için ek kod gerekmez. JSON paketi bir hedef türe Dönüştürülmeyen veriler içeriyorsa, serileştirme eylemi bir özel durum oluşturur.

  2. MainÖzellik değerlerini göstermek için yöntemini güncelleştirin:

    foreach (var repo in repositories)
    {
        Console.WriteLine(repo.Name);
        Console.WriteLine(repo.Description);
        Console.WriteLine(repo.GitHubHomeUrl);
        Console.WriteLine(repo.Homepage);
        Console.WriteLine(repo.Watchers);
        Console.WriteLine();
    }
    
  3. Uygulamayı çalıştırın.

    Listede artık ek özellikler yer almaktadır.

Tarih özelliği Ekle

Son gönderme işleminin tarihi JSON yanıtında bu biçimde biçimlendirilir:

2016-02-08T21:27:00Z

Bu biçim Eşgüdümlü Evrensel Saat (UTC) için olduğundan, seri durumdan çıkarma sonucu DateTime özelliği olan bir değerdir Kind Utc .

Saat diliminizde temsil edilen tarih ve saati almak için özel bir dönüştürme yöntemi yazmanız gerekir.

  1. Depo. cs' de, public TARIH ve saatin UTC temsili ve LastPush readonly yerel saate Dönüştürülecek tarihi döndüren bir özellik için bir özellik ekleyin:

    [JsonPropertyName("pushed_at")]
    public DateTime LastPushUtc { get; set; }
    
    public DateTime LastPush => LastPushUtc.ToLocalTime();
    

    LastPushÖzelliği, erişimci için ifade-Bodied üyesi kullanılarak tanımlanır get . setErişimci yok. setErişimcinin atlanması, C# ' de salt okunurdur bir özelliği tanımlamanın bir yoludur. (Evet, C# dilinde salt yazılır özellikler oluşturabilirsiniz, ancak bunların değeri sınırlı olur.)

  2. Program. cs dosyasında başka bir çıkış açıklaması ekleyin:

    Console.WriteLine(repo.LastPush);
    
  3. Uygulamayı çalıştırın.

    Çıktı, her depoya son gönderim tarihini ve saatini içerir.

Sonraki adımlar

Bu öğreticide, Web istekleri yapan ve sonuçları çözümleyen bir uygulama oluşturdunuz. Uygulama sürümünüz artık tamamlanmış örnekleeşleşmelidir.

.Net 'TEKI JSON serileştirme ve seri durumdan çıkarma (sıralama ve kaldırma)içinde JSON serileştirmesini yapılandırma hakkında daha fazla bilgi edinin.