Bir .NET istemcisinden (C#) bir Web API'si çağırmaCall a Web API From a .NET Client (C#)

tarafından Mike Wasson ve Rick Andersonby Mike Wasson and Rick Anderson

Tamamlanmış projeyi indirmek.Download Completed Project. Yükleme yönergeleri.Download instructions.

Bu öğretici, bir .NET uygulamasından web API'si çağırma nasıl gösterir kullanarak System.Net.Http.HttpClient.This tutorial shows how to call a web API from a .NET application, using System.Net.Http.HttpClient.

Bu öğreticide, aşağıdaki web API'si kullanan bir istemci uygulaması yazılır:In this tutorial, a client app is written that consumes the following web API:

EylemAction HTTP yöntemiHTTP method Göreli URI'siRelative URI
Bir ürün Kimliğine göre AlGet a product by ID ALGET /API'si/ürünler/kimliği/api/products/id
Yeni Ürün oluşturmaCreate a new product YAYINLAPOST / api/ürünleri/api/products
Bir ürün güncelleştirmesiUpdate a product PUTPUT /API'si/ürünler/kimliği/api/products/id
Bir ürün SilDelete a product DELETEDELETE /API'si/ürünler/kimliği/api/products/id

Bu API ile ASP.NET Web API'si uygulama hakkında bilgi edinmek için bkz: bu destekler CRUD işlemleri bir Web API'si oluşturma.To learn how to implement this API with ASP.NET Web API, see Creating a Web API that Supports CRUD Operations.

Kolaylık olması için istemci uygulaması Bu öğreticide bir Windows konsol uygulamasıdır.For simplicity, the client application in this tutorial is a Windows console application. HttpClient Windows Phone ve Windows Store uygulamaları için de desteklenir.HttpClient is also supported for Windows Phone and Windows Store apps. Daha fazla bilgi için yazma Web API İstemci kodu birden çok platformları kullanarak taşınabilir kitaplıklar içinFor more information, see Writing Web API Client Code for Multiple Platforms Using Portable Libraries

Konsol uygulaması oluşturunCreate the Console Application

Visual Studio'da adlı yeni bir Windows konsol uygulaması oluşturma HttpClientSample ve aşağıdaki kodu yapıştırın:In Visual Studio, create a new Windows console app named HttpClientSample and paste in the following code:

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace HttpClientSample
{
    public class Product
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }

    class Program
    {
        static HttpClient client = new HttpClient();

        static void ShowProduct(Product product)
        {
            Console.WriteLine($"Name: {product.Name}\tPrice: " +
                $"{product.Price}\tCategory: {product.Category}");
        }

        static async Task<Uri> CreateProductAsync(Product product)
        {
            HttpResponseMessage response = await client.PostAsJsonAsync(
                "api/products", product);
            response.EnsureSuccessStatusCode();

            // return URI of the created resource.
            return response.Headers.Location;
        }

        static async Task<Product> GetProductAsync(string path)
        {
            Product product = null;
            HttpResponseMessage response = await client.GetAsync(path);
            if (response.IsSuccessStatusCode)
            {
                product = await response.Content.ReadAsAsync<Product>();
            }
            return product;
        }

        static async Task<Product> UpdateProductAsync(Product product)
        {
            HttpResponseMessage response = await client.PutAsJsonAsync(
                $"api/products/{product.Id}", product);
            response.EnsureSuccessStatusCode();

            // Deserialize the updated product from the response body.
            product = await response.Content.ReadAsAsync<Product>();
            return product;
        }

        static async Task<HttpStatusCode> DeleteProductAsync(string id)
        {
            HttpResponseMessage response = await client.DeleteAsync(
                $"api/products/{id}");
            return response.StatusCode;
        }

        static void Main()
        {
            RunAsync().GetAwaiter().GetResult();
        }

        static async Task RunAsync()
        {
            // Update port # in the following line.
            client.BaseAddress = new Uri("http://localhost:64195/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            try
            {
                // Create a new product
                Product product = new Product
                {
                    Name = "Gizmo",
                    Price = 100,
                    Category = "Widgets"
                };

                var url = await CreateProductAsync(product);
                Console.WriteLine($"Created at {url}");

                // Get the product
                product = await GetProductAsync(url.PathAndQuery);
                ShowProduct(product);

                // Update the product
                Console.WriteLine("Updating price...");
                product.Price = 80;
                await UpdateProductAsync(product);

                // Get the updated product
                product = await GetProductAsync(url.PathAndQuery);
                ShowProduct(product);

                // Delete the product
                var statusCode = await DeleteProductAsync(product.Id);
                Console.WriteLine($"Deleted (HTTP Status = {(int)statusCode})");

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.ReadLine();
        }
    }
}

Yukarıdaki kod tam istemci uygulaması gereklidir.The preceding code is the complete client app.

RunAsync çalıştırır ve işlem tamamlanana kadar engeller.RunAsync runs and blocks until it completes. Çoğu HttpClient yöntemlerdir zaman uyumsuz, bunların ağ g/ç gerçekleştirdiğinden.Most HttpClient methods are async, because they perform network I/O. Zaman uyumsuz görevlerin tümünü içinde yapılır RunAsync.All of the async tasks are done inside RunAsync. Bir uygulama ana iş parçacığı normalde engellemez, ancak bu uygulama etkileşimi izin vermez.Normally an app doesn't block the main thread, but this app doesn't allow any interaction.

static async Task RunAsync()
{
    // Update port # in the following line.
    client.BaseAddress = new Uri("http://localhost:64195/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));

    try
    {
        // Create a new product
        Product product = new Product
        {
            Name = "Gizmo",
            Price = 100,
            Category = "Widgets"
        };

        var url = await CreateProductAsync(product);
        Console.WriteLine($"Created at {url}");

        // Get the product
        product = await GetProductAsync(url.PathAndQuery);
        ShowProduct(product);

        // Update the product
        Console.WriteLine("Updating price...");
        product.Price = 80;
        await UpdateProductAsync(product);

        // Get the updated product
        product = await GetProductAsync(url.PathAndQuery);
        ShowProduct(product);

        // Delete the product
        var statusCode = await DeleteProductAsync(product.Id);
        Console.WriteLine($"Deleted (HTTP Status = {(int)statusCode})");

    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

    Console.ReadLine();
}

Web API İstemci kitaplıklarını yüklemeInstall the Web API Client Libraries

NuGet paketi Web API İstemci kitaplıkları paketini yüklemek için Yöneticisi'ni kullanın.Use NuGet Package Manager to install the Web API Client Libraries package.

Gelen Araçları menüsünde NuGet Paket Yöneticisi > Paket Yöneticisi Konsolu.From the Tools menu, select NuGet Package Manager > Package Manager Console. Paket Yöneticisi Konsolu (PMC'de), aşağıdaki komutu yazın:In the Package Manager Console (PMC), type the following command:

Install-Package Microsoft.AspNet.WebApi.Client

Önceki komutta aşağıdaki NuGet paketleri projeye ekler:The preceding command adds the following NuGet packages to the project:

  • Microsoft.AspNet.WebApi.ClientMicrosoft.AspNet.WebApi.Client
  • Newtonsoft.JsonNewtonsoft.Json

Json.NET, .NET için popüler bir yüksek performanslı JSON çerçevedir.Json.NET is a popular high-performance JSON framework for .NET.

Bir Model sınıfı eklemeAdd a Model Class

İnceleme Product sınıfı:Examine the Product class:

public class Product
{
    public string Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
}

Bu sınıf, web API'si tarafından kullanılan veri modeli ile eşleşir.This class matches the data model used by the web API. Bir uygulama kullanabilirsiniz HttpClient okumak için bir Product bir HTTP yanıt örneği.An app can use HttpClient to read a Product instance from an HTTP response. Uygulama seri durumundan çıkarma kod yazmanız gerekmez.The app doesn't have to write any deserialization code.

Oluşturma ve HttpClient başlatmaCreate and Initialize HttpClient

Statik inceleyin HttpClient özelliği:Examine the static HttpClient property:

static HttpClient client = new HttpClient();

HttpClient kez oluşturulacak hedeflenen ve bir uygulamanın ömrü yeniden.HttpClient is intended to be instantiated once and reused throughout the life of an application. Aşağıdaki koşullar sonuçlanabilir SocketException hataları:The following conditions can result in SocketException errors:

  • Yeni bir oluşturma HttpClient istek başına örnek.Creating a new HttpClient instance per request.
  • Ağır yük altında sunucu.Server under heavy load.

Yeni bir oluşturma HttpClient istek başına örnek kullanılabilir yuva tüketebilir.Creating a new HttpClient instance per request can exhaust the available sockets.

Aşağıdaki kod başlatır HttpClient örneği:The following code initializes the HttpClient instance:

static async Task RunAsync()
{
    // Update port # in the following line.
    client.BaseAddress = new Uri("http://localhost:64195/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));

Yukarıdaki kod:The preceding code:

  • Taban URI HTTP istekleri için ayarlar.Sets the base URI for HTTP requests. Sunucu uygulamasında kullanılan bağlantı noktası için bağlantı noktası numarasını değiştirin.Change the port number to the port used in the server app. Uygulama bağlantı noktası sunucu uygulaması için kullanıldıkları sürece çalışmaz.The app won't work unless port for the server app is used.
  • "Application/json" için Accept üstbilgisini ayarlar.Sets the Accept header to "application/json". Bu üst bilgi ayarlama, JSON biçiminde veri göndermek sunucuyı söyler.Setting this header tells the server to send data in JSON format.

Kaynak almak için bir GET isteği gönderSend a GET request to retrieve a resource

Aşağıdaki kod, bir ürün için bir GET isteği gönderir:The following code sends a GET request for a product:

static async Task<Product> GetProductAsync(string path)
{
    Product product = null;
    HttpResponseMessage response = await client.GetAsync(path);
    if (response.IsSuccessStatusCode)
    {
        product = await response.Content.ReadAsAsync<Product>();
    }
    return product;
}

GetAsync yöntem, HTTP GET isteği gönderir.The GetAsync method sends the HTTP GET request. Yöntemi tamamlandığında döndürür bir HttpResponseMessage , HTTP yanıtı içerir.When the method completes, it returns an HttpResponseMessage that contains the HTTP response. Yanıt durum kodu bir başarı kodu ise yanıt gövdesi bir ürün JSON gösterimini içerir.If the status code in the response is a success code, the response body contains the JSON representation of a product. Çağrı ReadAsAsync JSON yükü için seri durumdan çıkarılacak bir Product örneği.Call ReadAsAsync to deserialize the JSON payload to a Product instance. ReadAsAsync yanıt gövdesi büyük olabileceğinden yöntemi zaman uyumsuz.The ReadAsAsync method is asynchronous because the response body can be arbitrarily large.

HttpClient HTTP yanıtı bir hata kodu içeriyorsa bir özel durum oluşturmaz.HttpClient does not throw an exception when the HTTP response contains an error code. Bunun yerine, IsSuccessStatusCode özelliği false durum bir hata kodu ise.Instead, the IsSuccessStatusCode property is false if the status is an error code. HTTP hata kodları özel durumlar olarak değerlendirilecek tercih ederseniz, çağrı HttpResponseMessage.EnsureSuccessStatusCode yanıt nesnesinde.If you prefer to treat HTTP error codes as exceptions, call HttpResponseMessage.EnsureSuccessStatusCode on the response object. EnsureSuccessStatusCode Durum kodu 200 aralığın dışında kalan bir özel durum oluşturur–299.EnsureSuccessStatusCode throws an exception if the status code falls outside the range 200–299. Unutmayın HttpClient diğer nedenlerle özel durumlar oluşturabilecek — Örneğin, istek zaman aşımına uğrar.Note that HttpClient can throw exceptions for other reasons — for example, if the request times out.

Medya türü Biçimlendiricileri serisini kaldırmak içinMedia-Type Formatters to Deserialize

Zaman ReadAsAsync çağrılır hiçbir parametre olmadan varsayılan kullandığı medya biçimlendiricileri yanıt gövdesini okumak için.When ReadAsAsync is called with no parameters, it uses a default set of media formatters to read the response body. Varsayılan biçimlendiricileri JSON, XML ve formu url kodlanmış verileri destekler.The default formatters support JSON, XML, and Form-url-encoded data.

Varsayılan biçimlendiricileri kullanmak yerine, için biçimlendiricileri listesi sağlayabilirsiniz ReadAsAsync yöntemi.Instead of using the default formatters, you can provide a list of formatters to the ReadAsAsync method. Biçimlendiricileri listesi kullanarak bir özel medya türü biçimlendiricisi varsa yararlı olur:Using a list of formatters is useful if you have a custom media-type formatter:

var formatters = new List<MediaTypeFormatter>() {
    new MyCustomFormatter(),
    new JsonMediaTypeFormatter(),
    new XmlMediaTypeFormatter()
};
resp.Content.ReadAsAsync<IEnumerable<Product>>(formatters);

Daha fazla bilgi için ASP.NET Web API 2'deki medya BiçimlendiricileriFor more information, see Media Formatters in ASP.NET Web API 2

Bir kaynak oluşturmak için bir POST isteği göndermeSending a POST Request to Create a Resource

Aşağıdaki kodu içeren bir POST isteği gönderir. bir Product JSON biçimindeki örneği:The following code sends a POST request that contains a Product instance in JSON format:

static async Task<Uri> CreateProductAsync(Product product)
{
    HttpResponseMessage response = await client.PostAsJsonAsync(
        "api/products", product);
    response.EnsureSuccessStatusCode();

    // return URI of the created resource.
    return response.Headers.Location;
}

PostAsJsonAsync yöntemi:The PostAsJsonAsync method:

  • Bir nesne json'a seri hale getirir.Serializes an object to JSON.
  • JSON yükü bir POST isteği gönderir.Sends the JSON payload in a POST request.

İstek başarılı olursa:If the request succeeds:

  • 201 (oluşturuldu) yanıt döndürmesi gerekir.It should return a 201 (Created) response.
  • Yanıt URL'si oluşturulan kaynakların konumu üst bilgisini içermelidir.The response should include the URL of the created resources in the Location header.

Bir kaynağı güncelleştirmek için PUT isteği göndermeSending a PUT Request to Update a Resource

Aşağıdaki kod, bir ürünü güncelleştirmek için PUT İsteği gönderir:The following code sends a PUT request to update a product:

static async Task<Product> UpdateProductAsync(Product product)
{
    HttpResponseMessage response = await client.PutAsJsonAsync(
        $"api/products/{product.Id}", product);
    response.EnsureSuccessStatusCode();

    // Deserialize the updated product from the response body.
    product = await response.Content.ReadAsAsync<Product>();
    return product;
}

PutAsJsonAsync yöntem çalışır gibi PostAsJsonAsyncdışında posta yerine bir PUT İsteği gönderir.The PutAsJsonAsync method works like PostAsJsonAsync, except that it sends a PUT request instead of POST.

Bir kaynağı silmek için bir silme isteği gönderiliyorSending a DELETE Request to Delete a Resource

Aşağıdaki kod, bir ürünü silmek için bir silme isteği gönderir:The following code sends a DELETE request to delete a product:

static async Task<HttpStatusCode> DeleteProductAsync(string id)
{
    HttpResponseMessage response = await client.DeleteAsync(
        $"api/products/{id}");
    return response.StatusCode;
}

GET gibi bir istek gövdesi bir silme isteği yok.Like GET, a DELETE request does not have a request body. DELETE ile JSON veya XML biçiminde belirtmeniz gerekmez.You don't need to specify JSON or XML format with DELETE.

Örnek testTest the sample

İstemci uygulamayı test etmek için:To test the client app:

  1. İndirme ve sunucu uygulamasını çalıştırın.Download and run the server app. Yükleme yönergeleri.Download instructions. Sunucu uygulamasının çalıştığı doğrulayın.Verify the server app is working. Exaxmple için http://localhost:64195/api/products ürünlerin listesini döndürmelidir.For exaxmple, http://localhost:64195/api/products should return a list of products.

  2. HTTP isteklerini temel URI'sini ayarlayın.Set the base URI for HTTP requests. Sunucu uygulamasında kullanılan bağlantı noktası için bağlantı noktası numarasını değiştirin.Change the port number to the port used in the server app.

    static async Task RunAsync()
    {
        // Update port # in the following line.
        client.BaseAddress = new Uri("http://localhost:64195/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    
  3. İstemci uygulaması çalıştırın.Run the client app. Aşağıdaki çıkış üretilir:The following output is produced:

    Created at http://localhost:64195/api/products/4
    Name: Gizmo     Price: 100.0    Category: Widgets
    Updating price...
    Name: Gizmo     Price: 80.0     Category: Widgets
    Deleted (HTTP Status = 204)