.NET Istemcisinden Web API 'SI çağırma (C#)Call a Web API From a .NET Client (C#)

, Mike, son ve Rick Anderson tarafındanby Mike Wasson and Rick Anderson

Tamamlanmış projeyi indirin.Download Completed Project. Yönergeleri indirin.Download instructions.

Bu öğreticide, System .net. http. HttpClient kullanılarak .NET uygulamasından BIR Web API 'sinin nasıl çağrılacağını gösterir.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 'sini tüketen bir istemci uygulaması yazılmıştır:In this tutorial, a client app is written that consumes the following web API:

EylemAction HTTP yöntemiHTTP method Göreli URIRelative URI
KIMLIĞE göre ürün alGet a product by ID GETGET /api/Products/ID/api/products/id
Yeni ürün oluşturCreate a new product POSTPOST /api/Products/api/products
Bir ürünü güncelleştirmeUpdate a product PUTPUT /api/Products/ID/api/products/id
Bir ürünü silmeDelete a product DELETEDELETE /api/Products/ID/api/products/id

Bu API 'yi ASP.NET Web API 'SI ile nasıl uygulayacağınızı öğrenmek için bkz. CRUD Işlemlerini destekleyen 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, bu öğreticideki istemci uygulaması bir Windows konsol uygulamasıdır.For simplicity, the client application in this tutorial is a Windows console application. HttpClient , Windows Phone ve Windows Mağazası uygulamaları için de desteklenir.HttpClient is also supported for Windows Phone and Windows Store apps. Daha fazla bilgi için bkz. Taşınabilir kitaplıkları kullanarak birden çok platform Için Web API Istemci kodu yazmaFor more information, see Writing Web API Client Code for Multiple Platforms Using Portable Libraries

Note: Temel URL 'Leri ve göreli URI 'Leri sabit kodlanmış değerler olarak geçirirseniz, API 'yi kullanmak için kuralların en az olması gerekir HttpClient .NOTE: If you pass base URLs and relative URIs as hard-coded values, be mindful of the rules for utilizing the HttpClient API. HttpClient.BaseAddressÖzelliği sondaki eğik çizgi () içeren bir adrese ayarlanmalıdır / .The HttpClient.BaseAddress property should be set to an address with a trailing forward slash (/). Örneğin, sabit kodlanmış kaynak URI 'Lerini HttpClient.GetAsync yönteme geçirirken önünde eğik çizgi eklemeyin.For example, when passing hard-coded resource URIs to the HttpClient.GetAsync method, don't include a leading forward slash. ProductKimliğe göre almak için:To get a Product by ID:

  1. Kurmakclient.BaseAddress = new Uri("https://localhost:5001/");Set client.BaseAddress = new Uri("https://localhost:5001/");
  2. İstek a Product .Request a Product. Örneğin, client.GetAsync<Product>("api/products/4");.For example, client.GetAsync<Product>("api/products/4");.

Konsol uygulaması oluşturmaCreate the Console Application

Visual Studio 'da Httpclientsample adlı yeni bir Windows konsol uygulaması oluşturun 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, tüm istemci uygulamasıdır.The preceding code is the complete client app.

RunAsyncçalışır ve tamamlanana kadar engeller.RunAsync runs and blocks until it completes. Ağ g/ç gerçekleştirdiklerinden, çoğu HttpClient yöntemi zaman uyumsuz.Most HttpClient methods are async, because they perform network I/O. Tüm zaman uyumsuz görevler içinde yapılır RunAsync .All of the async tasks are done inside RunAsync. Normalde bir uygulama ana iş parçacığını engellemez, ancak bu uygulama hiçbir etkileşime 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 Istemci kitaplıklarını yüklerInstall the Web API Client Libraries

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

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

Install-Package Microsoft.AspNet.WebApi.Client

Yukarıdaki komut, projeye aşağıdaki NuGet paketlerini ekler:The preceding command adds the following NuGet packages to the project:

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

Netmerak Soft. JSON (Json.NET olarak da bilinir), .NET için popüler bir yüksek performanslı JSON çerçevesidir.Netwonsoft.Json (also known as Json.NET) is a popular high-performance JSON framework for .NET.

Model sınıfı eklemeAdd a Model Class

Sınıfı inceleyin Product :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 modeliyle eşleşir.This class matches the data model used by the web API. Bir uygulama, HTTP yanıtından bir örnek okumak için HttpClient kullanabilir Product .An app can use HttpClient to read a Product instance from an HTTP response. Uygulamanın seri durumdan çıkarma kodu yazmak zorunda değildir.The app doesn't have to write any deserialization code.

HttpClient oluşturma ve başlatmaCreate and Initialize HttpClient

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

static HttpClient client = new HttpClient();

HttpClient uygulamasının bir kez oluşturulması ve bir uygulamanın ömrü boyunca yeniden kullanılması amaçlanmıştır.HttpClient is intended to be instantiated once and reused throughout the life of an application. Aşağıdaki koşullar, SocketException hatalarına neden olabilir:The following conditions can result in SocketException errors:

  • İstek başına yeni bir HttpClient örneği oluşturuluyor.Creating a new HttpClient instance per request.
  • Sunucu ağır yük altında.Server under heavy load.

Her istek için yeni bir HttpClient örneği oluşturulması, kullanılabilir yuvaları tüketebilir.Creating a new HttpClient instance per request can exhaust the available sockets.

Aşağıdaki kod, HttpClient örneğini başlatır: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:

  • HTTP istekleri için temel URI 'yi ayarlar.Sets the base URI for HTTP requests. Bağlantı noktası numarasını sunucu uygulamasında kullanılan bağlantı noktasıyla değiştirin.Change the port number to the port used in the server app. Sunucu uygulaması için bağlantı noktası kullanılmadığı takdirde uygulama çalışmaz.The app won't work unless port for the server app is used.
  • Accept üst bilgisini "Application/JSON" olarak ayarlar.Sets the Accept header to "application/json". Bu üst bilgiyi ayarlamak, sunucuya verileri JSON biçiminde göndermesini söyler.Setting this header tells the server to send data in JSON format.

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

Aşağıdaki kod, bir ürün için 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ÖNTEMI http get isteğini gönderir.The GetAsync method sends the HTTP GET request. Yöntem tamamlandığında, HTTP yanıtını içeren bir HttpResponseMessage döndürür.When the method completes, it returns an HttpResponseMessage that contains the HTTP response. Yanıttaki durum kodu bir başarı kodu ise, yanıt gövdesi bir ürünü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. JSON yükünün bir örneğe serisini kaldırmak için Readasasync çağrısı yapın Product .Call ReadAsAsync to deserialize the JSON payload to a Product instance. Yanıt gövdesi çok büyük olabileceğinden Readasasync yöntemi zaman uyumsuzdur.The ReadAsAsync method is asynchronous because the response body can be arbitrarily large.

HTTP yanıtı bir hata kodu içerdiğinde HttpClient bir özel durum oluşturmaz.HttpClient does not throw an exception when the HTTP response contains an error code. Bunun yerine, durum bir hata kodu ise IsSuccessStatusCode özelliği false 'tur .Instead, the IsSuccessStatusCode property is false if the status is an error code. HTTP hata kodlarını özel durumlar olarak kabul etmek isterseniz, yanıt nesnesinde HttpResponseMessage. EnsureSuccessStatusCode öğesini çağırın.If you prefer to treat HTTP error codes as exceptions, call HttpResponseMessage.EnsureSuccessStatusCode on the response object. EnsureSuccessStatusCodedurum kodu 200 299 aralığının dışında kalırsa bir özel durum oluşturur – .EnsureSuccessStatusCode throws an exception if the status code falls outside the range 200–299. HttpClient — , istek zaman aşımına uğrarsa diğer nedenlerle özel durumlar oluşturabilir.Note that HttpClient can throw exceptions for other reasons — for example, if the request times out.

Seri durumdan çıkarılacak medya türü FormatlayıcılarıMedia-Type Formatters to Deserialize

Readasasync parametresi olmadan çağrıldığında, yanıt gövdesini okumak için varsayılan medya formatlayıcıları kümesini kullanır.When ReadAsAsync is called with no parameters, it uses a default set of media formatters to read the response body. Varsayılan biçim JSON, XML ve form-URL kodlamalı verileri destekler.The default formatters support JSON, XML, and Form-url-encoded data.

Varsayılan biçimleri kullanmak yerine, Readasasync yöntemine bir formatınters listesi sağlayabilirsiniz.Instead of using the default formatters, you can provide a list of formatters to the ReadAsAsync method. Özel bir medya türü biçimlendirici varsa, bir biçim listesinin kullanılması 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 bkz. ASP.NET Web API 2 ' de medya biçimleriFor more information, see Media Formatters in ASP.NET Web API 2

Kaynak oluşturmak için POST Isteği göndermeSending a POST Request to Create a Resource

Aşağıdaki kod, JSON biçiminde bir örnek içeren bir POST isteği gönderir Product :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 nesneyi JSON 'a dizleştirir.Serializes an object to JSON.
  • JSON yükünü bir POST isteğinde gönderir.Sends the JSON payload in a POST request.

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

  • Bu, 201 (oluşturulan) yanıtı döndürmelidir.It should return a 201 (Created) response.
  • Yanıt, konum üstbilgisindeki oluşturulan kaynakların URL 'sini 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 bir PUT isteğ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öntemi, post yerıne bir PUT isteği göndermesi dışında, postasjsonasyncyöntemi gibi çalışmaktadır.The PutAsJsonAsync method works like PostAsJsonAsync, except that it sends a PUT request instead of POST.

Bir kaynağı silmek için SILME Isteği göndermeSending 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 DELETE isteğinin bir istek gövdesi yoktur.Like GET, a DELETE request does not have a request body. DELETE ile JSON veya XML biçimi belirtmeniz gerekmez.You don't need to specify JSON or XML format with DELETE.

Örneği test etmeTest the sample

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

  1. Sunucu uygulamasını indirip çalıştırın.Download and run the server app. Yönergeleri indirin.Download instructions. Sunucu uygulamasının çalıştığını doğrulayın.Verify the server app is working. Örneğin, http://localhost:64195/api/products ürünlerin bir listesini döndürmelidir.For example, http://localhost:64195/api/products should return a list of products.

  2. HTTP istekleri için temel URI 'yi ayarlayın.Set the base URI for HTTP requests. Bağlantı noktası numarasını sunucu uygulamasında kullanılan bağlantı noktasıyla 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ını çalıştırın.Run the client app. Aşağıdaki çıktı ü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)