مقدمه

در درس‌های گذشته، یک وب‌سرویس API کامل برای پایگاه داده‌ی Northwind ساختیم و دیدیم که چگونه می‌توان آن را با استفاده از ابزارهایی مانند Swagger UI تست کرد. اما هدف نهایی یک API این است که توسط یک برنامه‌ی کلاینت (Client Application) مصرف (consume) شود. این کلاینت می‌تواند یک اپلیکیشن وب نوشته شده با جاوااسکریپت، یک اپلیکیشن موبایل، یک برنامه‌ی دسکتاپ یا حتی یک سرویس دیگر در سمت سرور باشد.

فرآیند استفاده از یک API شامل ارسال درخواست‌های HTTP به نقاط پایانی (endpoints) آن و سپس پردازش پاسخ‌های دریافتی (معمولاً در فرمت JSON) است. در این درس، ما یک اپلیکیشن کنسول ساده به عنوان کلاینت می‌سازیم و یاد می‌گیریم که چگونه با استفاده از کلاس مدرن و قدرتمند HttpClient، با وب‌سرویس Northwind که ساخته‌ایم، تعامل داشته باشیم.

HttpClient: ابزار اصلی برای ارسال درخواست‌های HTTP

کلاس System.Net.Http.HttpClient ابزار اصلی و مدرن در .NET برای ارسال درخواست‌های HTTP و دریافت پاسخ‌های آن‌ها به صورت ناهمزمان (asynchronously) است. این کلاس برای استفاده‌ی مجدد طراحی شده و بهترین رویه این است که یک نمونه‌ی واحد از آن را برای تمام طول عمر اپلیکیشن خود ایجاد کرده و به اشتراک بگذارید.

قدم اول: ساخت اپلیکیشن کلاینت

ابتدا یک پروژه‌ی جدید از نوع Console App ایجاد کرده و نام آن را ApiClient می‌گذاریم. برای اینکه بتوانیم پاسخ‌های JSON را به راحتی به اشیاء C# تبدیل کنیم، پکیج Newtonsoft.Json را نیز به این پروژه اضافه می‌کنیم:

Copy Icon Terminal
dotnet add package Newtonsoft.Json

همچنین، باید تعریف کلاس Customer را که در پروژه‌ی API وجود دارد، در پروژه‌ی کلاینت خود نیز داشته باشیم تا بتوانیم داده‌های JSON را به آن دی‌سریالایز کنیم.

قدم دوم: خواندن داده‌ها با GET

بیایید یک متد ناهمزمان بنویسیم که تمام مشتریان را از نقطه‌ی پایانی /api/customers وب‌سرویس ما دریافت کند.

Copy Icon Program.cs
using System.Net.Http;
using Newtonsoft.Json;

// It's best practice to create one HttpClient instance and reuse it.
static readonly HttpClient client = new();

static async Task Main()
{
    // Make sure your Northwind.Api project is running first!
    string apiUrl = "https://localhost:7001/api/customers"; // Adjust port if necessary

    try
    {
        // 1. Send an asynchronous GET request.
        HttpResponseMessage response = await client.GetAsync(apiUrl);
        response.EnsureSuccessStatusCode(); // Throws an exception if the status code is not 2xx.
        
        // 2. Read the response content as a string.
        string responseBody = await response.Content.ReadAsStringAsync();
        
        // 3. Deserialize the JSON string to a list of Customer objects.
        var customers = JsonConvert.DeserializeObject<List<Customer>>(responseBody);
        
        Console.WriteLine("--- Customers ---");
        foreach (var customer in customers.Take(5))
        {
            Console.WriteLine(customer.CompanyName);
        }
    }
    catch (HttpRequestException e)
    {
        Console.WriteLine($"\nException Caught! Message :{e.Message}");
    }
}

نکات کلیدی:

  • تمام متدهای HttpClient ناهمزمان هستند و باید با await فراخوانی شوند.
  • متد GetAsync یک درخواست GET را ارسال کرده و یک HttpResponseMessage را برمی‌گرداند.
  • متد EnsureSuccessStatusCode() یک روش راحت برای بررسی این است که آیا درخواست موفقیت‌آمیز بوده یا خیر (کد وضعیت در محدوده‌ی 200-299).
  • ما محتوای پاسخ را به صورت یک رشته خوانده و سپس با استفاده از JsonConvert آن را به لیستی از اشیاء Customer تبدیل می‌کنیم.

ارسال داده‌ها با POST

برای ایجاد یک مشتری جدید، باید یک درخواست POST به نقطه‌ی پایانی /api/customers ارسال کنیم و داده‌های مشتری جدید را در بدنه‌ی درخواست و در فرمت JSON قرار دهیم.

Copy Icon Program.cs
static async Task CreateCustomerAsync()
{
    var newCustomer = new 
    { 
        CustomerId = "TEST1", 
        CompanyName = "Test Company", 
        ContactName = "John Test" 
    };

    // 1. Serialize our C# object to a JSON string.
    string json = JsonConvert.SerializeObject(newCustomer);

    // 2. Create StringContent with the correct encoding and media type.
    StringContent data = new StringContent(json, Encoding.UTF8, "application/json");

    string url = "https://localhost:7001/api/customers";
    
    // 3. Send the POST request.
    HttpResponseMessage response = await client.PostAsync(url, data);

    response.EnsureSuccessStatusCode();

    Console.WriteLine("Customer created successfully!");
}

در این کد، ما ابتدا شیء C# خود را به یک رشته‌ی JSON سریالایز می‌کنیم. سپس، یک نمونه از کلاس StringContent می‌سازیم تا این رشته را به همراه انکدینگ صحیح (UTF-8) و نوع مدیا (application/json) در بدنه‌ی درخواست قرار دهیم. در نهایت، با استفاده از متد PostAsync، درخواست را ارسال می‌کنیم.