Basit Bir Rest Api Client Geliştirelim 2
2023-05-12
Bu versiyonda, bir dizi başlık bilgisi, özelleştirilmiş zaman aşımı süresi ve daha fazla hata kontrolü ekleyelim:
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public class MyHttpClient : IDisposable
{
private readonly HttpClient _client;
public MyHttpClient(TimeSpan? timeout = null)
{
_client = new HttpClient();
if (timeout.HasValue)
{
_client.Timeout = timeout.Value;
}
}
private HttpRequestMessage CreateRequest(string uri, HttpMethod method, string jsonData = null, Dictionary<string, string> headers = null)
{
var request = new HttpRequestMessage(method, uri);
if (headers != null)
{
foreach (var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
if (!string.IsNullOrWhiteSpace(jsonData))
{
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
}
return request;
}
public async Task<HttpResponseMessage> SendRequestAsync(string uri, HttpMethod method, string jsonData = null, Dictionary<string, string> headers = null)
{
var request = CreateRequest(uri, method, jsonData, headers);
try
{
var response = await _client.SendAsync(request);
response.EnsureSuccessStatusCode();
return response;
}
catch (HttpRequestException ex)
{
throw new Exception($"{method} request to {uri} failed.", ex);
}
}
public async Task<string> GetAsync(string uri, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Get, null, headers)).Content.ReadAsStringAsync().Result;
public async Task<string> PostAsync(string uri, string jsonData, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Post, jsonData, headers)).Content.ReadAsStringAsync().Result;
public async Task<string> PutAsync(string uri, string jsonData, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Put, jsonData, headers)).Content.ReadAsStringAsync().Result;
public async Task<string> DeleteAsync(string uri, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Delete, null, headers)).Content.ReadAsStringAsync().Result;
public void Dispose()
{
_client?.Dispose();
}
}
Bu sınıf, IDisposable
interface’ini uygular, bu da HttpClient
nesnesini düzgün bir şekilde yok etmenizi sağlar. Yapıcı
(constructor
), isteğe bağlı bir zaman aşımı süresi alır ve HttpClient
‘ın Timeout
özelliğini ayarlar.
SendRequestAsync
metodu, istek oluşturma işlemini ayrı bir CreateRequest
metoduna ayırır. Bu, kodun okunabilirliğini artırır ve istek oluşturma sürecinde daha fazla özelleştirmeye izin verir.
Ayrıca, SendRequestAsync
metodu artık bir HttpResponseMessage
döndürür, böylece istemci isteğin yanıt durum kodunu ve diğer özelliklerini kontrol edebilir.
HTTP istemcilerini daha verimli bir şekilde yönetmek için HttpClientFactory
kullanalım, çünkü HttpClientFactory
altta yatan
HttpClientHandler
nesnelerini yönetir ve sunucu DNS değişikliklerini daha iyi ele alır.
Ek olarak, bu sınıf artık özelleştirilebilir bir HttpMessageHandler
kabul ediyor, bu da istemcinin daha fazla özelleştirilebilirliğine olanak sağlıyor.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public class MyHttpClient : IDisposable
{
private readonly HttpClient _client;
public MyHttpClient(HttpClient client)
{
_client = client;
}
private HttpRequestMessage CreateRequest(string uri, HttpMethod method, string jsonData = null, Dictionary<string, string> headers = null)
{
var request = new HttpRequestMessage(method, uri);
if (headers != null)
{
foreach (var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
if (!string.IsNullOrWhiteSpace(jsonData))
{
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
}
return request;
}
public async Task<HttpResponseMessage> SendRequestAsync(string uri, HttpMethod method, string jsonData = null, Dictionary<string, string> headers = null)
{
var request = CreateRequest(uri, method, jsonData, headers);
try
{
var response = await _client.SendAsync(request);
response.EnsureSuccessStatusCode();
return response;
}
catch (HttpRequestException ex)
{
throw new Exception($"{method} request to {uri} failed.", ex);
}
}
public async Task<string> GetAsync(string uri, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Get, null, headers)).Content.ReadAsStringAsync().Result;
public async Task<string> PostAsync(string uri, string jsonData, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Post, jsonData, headers)).Content.ReadAsStringAsync().Result;
public async Task<string> PutAsync(string uri, string jsonData, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Put, jsonData, headers)).Content.ReadAsStringAsync().Result;
public async Task<string> DeleteAsync(string uri, Dictionary<string, string> headers = null) =>
(await SendRequestAsync(uri, HttpMethod.Delete, null, headers)).Content.ReadAsStringAsync().Result;
public void Dispose()
{
_client?.Dispose();
}
}
Bu sınıfı bir HttpClientFactory
ile kullanmak için aşağıdaki gibi bir şey yapabilirsiniz:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<MyHttpClient>();
}
Ve sonra istemciyi aşağıdaki gibi enjekte edebilirsiniz:
public class MyController : ControllerBase
{
private readonly MyHttpClient _client;
public MyController(MyHttpClient client)
{
_client = client;
}
}