HttpClient sınıfıyla HTTP istekleri yapma
Bu makalede, HTTP istekleri yapmayı ve sınıfıyla yanıtları işlemeyi HttpClient
öğreneceksiniz.
Önemli
Örnek HTTP isteklerinin tümü aşağıdaki URL'lerden birini hedefler:
- https://jsonplaceholder.typicode.com: Test ve prototip oluşturma için ücretsiz sahte API.
- https://www.example.com: Bu etki alanı, belgelerdeki örneklerde kullanıma yöneliktir.
HTTP uç noktaları genellikle JavaScript Nesne Gösterimi (JSON) verilerini döndürür, ancak her zaman döndürmez. Kolaylık olması için, isteğe bağlı System.Net.Http.Json NuGet paketi ve için HttpContent
HttpClient
kullanarak otomatik serileştirme ve seri durumdan çıkarma System.Text.Json
gerçekleştiren çeşitli uzantı yöntemleri sağlar. İzleyen örnekler, bu uzantıların kullanılabildiği yerlere dikkat çekmektedir.
İpucu
Bu makaledeki tüm kaynak kodu GitHub: .NET Docs deposunda bulabilirsiniz.
Oluşturma HttpClient
Aşağıdaki örneklerin çoğu aynı HttpClient
örneği yeniden kullandığından yalnızca bir kez yapılandırılması gerekir. oluşturmak HttpClient
için sınıf oluşturucuyu HttpClient
kullanın. Daha fazla bilgi için bkz . HttpClient kullanma yönergeleri.
// HttpClient lifecycle management best practices:
// https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use
private static HttpClient sharedClient = new()
{
BaseAddress = new Uri("https://jsonplaceholder.typicode.com"),
};
Yukarıdaki kod:
- Yeni
HttpClient
bir örneği değişken olarak başlatırstatic
. Yönergelere göre, uygulamanın yaşam döngüsü boyunca örneklerin yeniden kullanılmasıHttpClient
önerilir. - öğesini olarak HttpClient.BaseAddress
"https://jsonplaceholder.typicode.com"
ayarlar.
Bu HttpClient
örnek, sonraki istekleri yaparken temel adresi kullanır. Diğer yapılandırmaları uygulamak için şunları göz önünde bulundurun:
- ayarı.HttpClient.DefaultRequestHeaders
- Bir nondefault HttpClient.Timeoutuygulama.
- öğesini HttpClient.DefaultRequestVersionbelirtme.
İpucu
Alternatif olarak, istediğiniz sayıda istemciyi yapılandırmanıza ve bunları bağımlılık ekleme hizmetleri olarak kullanmanıza olanak tanıyan bir fabrika düzeni yaklaşımı kullanarak örnekler oluşturabilirsiniz HttpClient
. Daha fazla bilgi için bkz . .NET ile HTTP istemci fabrikası.
HTTP isteğinde bulunma
HTTP isteğinde bulunmak için aşağıdaki API'lerden herhangi birini çağırırsınız:
HTTP yöntemi | API |
---|---|
GET |
HttpClient.GetAsync |
GET |
HttpClient.GetByteArrayAsync |
GET |
HttpClient.GetStreamAsync |
GET |
HttpClient.GetStringAsync |
POST |
HttpClient.PostAsync |
PUT |
HttpClient.PutAsync |
PATCH |
HttpClient.PatchAsync |
DELETE |
HttpClient.DeleteAsync |
†USER SPECIFIED |
HttpClient.SendAsync |
†A
USER SPECIFIED
isteği, yönteminSendAsync
geçerli HttpMethodbir kabul ettiğini gösterir.
Uyarı
HTTP isteklerinde bulunmak ağ G/Ç'ye bağlı iş olarak kabul edilir. Zaman uyumlu HttpClient.Send bir yöntem olsa da, bunu yapmak için iyi bir nedeniniz yoksa, bunun yerine zaman uyumsuz API'leri kullanmanız önerilir.
Not
Android cihazları hedeflerken (.NET MAUI geliştirmesi gibi), AndroidManifest.xml'a<application></application>
eklemeniz android:usesCleartextTraffic="true"
gerekir. Bu, Android güvenlik ilkeleri nedeniyle varsayılan olarak devre dışı bırakılan HTTP istekleri gibi düz metin trafiğine olanak tanır. Aşağıdaki örnek XML ayarlarını göz önünde bulundurun:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:usesCleartextTraffic="true"></application>
<!-- omitted for brevity -->
</manifest>
Daha fazla bilgi için bkz . Localhost etki alanı için düz metin ağ trafiğini etkinleştirme.
HTTP içeriği
Türü HttpContent , bir HTTP varlık gövdesini ve ilgili içerik üst bilgilerini temsil etmek için kullanılır. Gövde, POST
, PUT
ve PATCH
gerektiren HTTP yöntemleri (veya istek yöntemleri) için, isteğin HttpContent gövdesini belirtmek için sınıfını kullanırsınız. Çoğu örnek, alt sınıfın StringContent bir JSON yüküyle nasıl hazırlayacağını gösterir, ancak farklı içerik (MIME) türleri için başka alt sınıflar vardır.
- ByteArrayContent: Bayt dizisine dayalı HTTP içeriği sağlar.
- FormUrlEncodedContent: MIME türü kullanılarak
"application/x-www-form-urlencoded"
kodlanmış ad/değer demetleri için HTTP içeriği sağlar. - JsonContent: JSON tabanlı HTTP içeriği sağlar.
- MultipartContent: MIME türü belirtimi kullanılarak seri hale getirilen HttpContent nesnelerinin
"multipart/*"
bir koleksiyonunu sağlar. - MultipartFormDataContent: MIME türü kullanılarak
"multipart/form-data"
kodlanmış içerik için bir kapsayıcı sağlar. - ReadOnlyMemoryContent: bir ReadOnlyMemory<T>tabanlı HTTP içeriği sağlar.
- StreamContent: Bir akışı temel alan HTTP içeriği sağlar.
- StringContent: Bir dizeyi temel alan HTTP içeriği sağlar.
HttpContent
sınıfı, özelliğinde HttpResponseMessage.Content erişilebilen yanıt gövdesini HttpResponseMessagetemsil etmek için de kullanılır.
HTTP Al
İstek GET
bir gövde göndermemelidir ve bir kaynaktan veri almak (veya almak) için kullanılır (yöntem adından da belirtildiği gibi). bir ve URI'sine sahip bir HttpClient
HTTP GET
isteğinde bulunmak için yöntemini kullanınHttpClient.GetAsync:
static async Task GetAsync(HttpClient httpClient)
{
using HttpResponseMessage response = await httpClient.GetAsync("todos/3");
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{jsonResponse}\n");
// Expected output:
// GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1
// {
// "userId": 1,
// "id": 3,
// "title": "fugiat veniam minus",
// "completed": false
// }
}
Yukarıdaki kod:
- adresine
"https://jsonplaceholder.typicode.com/todos/3"
birGET
istekte bulunur. - Yanıtın başarılı olmasını sağlar.
- İstek ayrıntılarını konsola yazar.
- Yanıt gövdesini dize olarak okur.
- JSON yanıt gövdesini konsola yazar.
WriteRequestToConsole
, çerçevenin parçası olmayan özel bir uzantı yöntemidir, ancak nasıl uygulandığını merak ediyorsanız aşağıdaki C# kodunu göz önünde bulundurun:
static class HttpResponseMessageExtensions
{
internal static void WriteRequestToConsole(this HttpResponseMessage response)
{
if (response is null)
{
return;
}
var request = response.RequestMessage;
Console.Write($"{request?.Method} ");
Console.Write($"{request?.RequestUri} ");
Console.WriteLine($"HTTP/{request?.Version}");
}
}
Bu işlevsellik, istek ayrıntılarını konsola aşağıdaki biçimde yazmak için kullanılır:
<HTTP Request Method> <Request URI> <HTTP/Version>
Örneğin, isteği https://jsonplaceholder.typicode.com/todos/3
aşağıdaki GET
iletiyi döndürür:
GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1
JSON'dan HTTP Alma
Uç https://jsonplaceholder.typicode.com/todos nokta, "todo" nesnelerinden oluşan bir JSON dizisi döndürür. JSON yapıları aşağıdakine benzer:
[
{
"userId": 1,
"id": 1,
"title": "example title",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "another example title",
"completed": true
},
]
C# Todo
nesnesi aşağıdaki gibi tanımlanır:
public record class Todo(
int? UserId = null,
int? Id = null,
string? Title = null,
bool? Completed = null);
İsteğe bağlı Id
, , Title
Completed
ve UserId
özelliklerine sahip bir record class
tür. Tür hakkında record
daha fazla bilgi için bkz . C# dilinde kayıt türlerine giriş. İstekleri otomatik olarak seri durumdan GET
çıkararak kesin türdeki C# nesnesine getirmek için System.Net.Http.Json NuGet paketinin parçası olan uzantı yöntemini kullanınGetFromJsonAsync.
static async Task GetFromJsonAsync(HttpClient httpClient)
{
var todos = await httpClient.GetFromJsonAsync<List<Todo>>(
"todos?userId=1&completed=false");
Console.WriteLine("GET https://jsonplaceholder.typicode.com/todos?userId=1&completed=false HTTP/1.1");
todos?.ForEach(Console.WriteLine);
Console.WriteLine();
// Expected output:
// GET https://jsonplaceholder.typicode.com/todos?userId=1&completed=false HTTP/1.1
// Todo { UserId = 1, Id = 1, Title = delectus aut autem, Completed = False }
// Todo { UserId = 1, Id = 2, Title = quis ut nam facilis et officia qui, Completed = False }
// Todo { UserId = 1, Id = 3, Title = fugiat veniam minus, Completed = False }
// Todo { UserId = 1, Id = 5, Title = laboriosam mollitia et enim quasi adipisci quia provident illum, Completed = False }
// Todo { UserId = 1, Id = 6, Title = qui ullam ratione quibusdam voluptatem quia omnis, Completed = False }
// Todo { UserId = 1, Id = 7, Title = illo expedita consequatur quia in, Completed = False }
// Todo { UserId = 1, Id = 9, Title = molestiae perspiciatis ipsa, Completed = False }
// Todo { UserId = 1, Id = 13, Title = et doloremque nulla, Completed = False }
// Todo { UserId = 1, Id = 18, Title = dolorum est consequatur ea mollitia in culpa, Completed = False }
}
Önceki kodda:
GET
öğesine bir istek yapılır"https://jsonplaceholder.typicode.com/todos?userId=1&completed=false"
.- Sorgu dizesi, isteğin filtreleme ölçütlerini temsil eder.
- Yanıt, başarılı olduğunda otomatik olarak seri
List<Todo>
durumdan çıkarılır. - İstek ayrıntıları, her
Todo
nesneyle birlikte konsola yazılır.
HTTP Gönderisi
İstek POST
, işlenmek üzere sunucuya veri gönderir. Content-Type
İsteğin üst bilgisi, gövdenin gönderdiği MIME türünü gösterir. ve Uriverilen HttpClient
bir HTTP POST
isteğinde bulunmak için yöntemini kullanınHttpClient.PostAsync:
static async Task PostAsync(HttpClient httpClient)
{
using StringContent jsonContent = new(
JsonSerializer.Serialize(new
{
userId = 77,
id = 1,
title = "write code sample",
completed = false
}),
Encoding.UTF8,
"application/json");
using HttpResponseMessage response = await httpClient.PostAsync(
"todos",
jsonContent);
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{jsonResponse}\n");
// Expected output:
// POST https://jsonplaceholder.typicode.com/todos HTTP/1.1
// {
// "userId": 77,
// "id": 201,
// "title": "write code sample",
// "completed": false
// }
}
Yukarıdaki kod:
- İsteğin JSON gövdesine (MIME türü
"application/json"
) sahip bir StringContent örneği hazırlar. - adresine
"https://jsonplaceholder.typicode.com/todos"
birPOST
istekte bulunur. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını konsola yazar.
- Yanıt gövdesini konsola dize olarak yazar.
JSON olarak HTTP Gönderisi
İstek bağımsız değişkenlerini otomatik olarak seri hale POST
getirmek ve yanıtları kesin türü belirlenmiş C# nesnelerine seri durumdan çıkarmak için System.Net.Http.Json NuGet paketinin parçası olan uzantı yöntemini kullanınPostAsJsonAsync.
static async Task PostAsJsonAsync(HttpClient httpClient)
{
using HttpResponseMessage response = await httpClient.PostAsJsonAsync(
"todos",
new Todo(UserId: 9, Id: 99, Title: "Show extensions", Completed: false));
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var todo = await response.Content.ReadFromJsonAsync<Todo>();
Console.WriteLine($"{todo}\n");
// Expected output:
// POST https://jsonplaceholder.typicode.com/todos HTTP/1.1
// Todo { UserId = 9, Id = 201, Title = Show extensions, Completed = False }
}
Yukarıdaki kod:
- Örneği JSON olarak seri hale
Todo
getirir ve isteğinde"https://jsonplaceholder.typicode.com/todos"
bulunurPOST
. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını konsola yazar.
- Yanıt gövdesini bir
Todo
örneğe seri durumdan çıkartırTodo
ve konsola yazar.
HTTP Put
PUT
İstek yöntemi mevcut bir kaynağın yerini alır veya istek gövdesi yükünü kullanarak yeni bir kaynak oluşturur. bir ve URI'sine sahip bir HttpClient
HTTP PUT
isteğinde bulunmak için yöntemini kullanınHttpClient.PutAsync:
static async Task PutAsync(HttpClient httpClient)
{
using StringContent jsonContent = new(
JsonSerializer.Serialize(new
{
userId = 1,
id = 1,
title = "foo bar",
completed = false
}),
Encoding.UTF8,
"application/json");
using HttpResponseMessage response = await httpClient.PutAsync(
"todos/1",
jsonContent);
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{jsonResponse}\n");
// Expected output:
// PUT https://jsonplaceholder.typicode.com/todos/1 HTTP/1.1
// {
// "userId": 1,
// "id": 1,
// "title": "foo bar",
// "completed": false
// }
}
Yukarıdaki kod:
- İsteğin JSON gövdesine (MIME türü
"application/json"
) sahip bir StringContent örneği hazırlar. - adresine
"https://jsonplaceholder.typicode.com/todos/1"
birPUT
istekte bulunur. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını ve JSON yanıt gövdesini konsola yazar.
JSON olarak HTTP Put
İstek bağımsız değişkenlerini otomatik olarak seri hale PUT
getirmek ve yanıtları kesin olarak yazılan C# nesnelerine seri durumdan çıkarmak için System.Net.Http.Json NuGet paketinin parçası olan uzantı yöntemini kullanınPutAsJsonAsync.
static async Task PutAsJsonAsync(HttpClient httpClient)
{
using HttpResponseMessage response = await httpClient.PutAsJsonAsync(
"todos/5",
new Todo(Title: "partially update todo", Completed: true));
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var todo = await response.Content.ReadFromJsonAsync<Todo>();
Console.WriteLine($"{todo}\n");
// Expected output:
// PUT https://jsonplaceholder.typicode.com/todos/5 HTTP/1.1
// Todo { UserId = , Id = 5, Title = partially update todo, Completed = True }
}
Yukarıdaki kod:
- Örneği JSON olarak seri hale
Todo
getirir ve isteğinde"https://jsonplaceholder.typicode.com/todos/5"
bulunurPUT
. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını konsola yazar.
- Yanıt gövdesini bir
Todo
örneğe seri durumdan çıkartırTodo
ve konsola yazar.
HTTP Düzeltme Eki
İstek PATCH
, var olan bir kaynağın kısmi bir güncelleştirmesidir. Yeni bir kaynak oluşturmaz ve mevcut bir kaynağın yerini almak için tasarlanmamıştır. Bunun yerine, bir kaynağı yalnızca kısmen güncelleştirir. bir ve URI'sine sahip bir HttpClient
HTTP PATCH
isteğinde bulunmak için yöntemini kullanınHttpClient.PatchAsync:
static async Task PatchAsync(HttpClient httpClient)
{
using StringContent jsonContent = new(
JsonSerializer.Serialize(new
{
completed = true
}),
Encoding.UTF8,
"application/json");
using HttpResponseMessage response = await httpClient.PatchAsync(
"todos/1",
jsonContent);
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{jsonResponse}\n");
// Expected output
// PATCH https://jsonplaceholder.typicode.com/todos/1 HTTP/1.1
// {
// "userId": 1,
// "id": 1,
// "title": "delectus aut autem",
// "completed": true
// }
}
Yukarıdaki kod:
- İsteğin JSON gövdesine (MIME türü
"application/json"
) sahip bir StringContent örneği hazırlar. - adresine
"https://jsonplaceholder.typicode.com/todos/1"
birPATCH
istekte bulunur. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını ve JSON yanıt gövdesini konsola yazar.
NuGet paketindeki System.Net.Http.Json
istekler için PATCH
uzantı yöntemi yok.
HTTP Silme
İstek DELETE
var olan bir kaynağı siler. İstek DELETE
bir kez etkili olur ancak güvenli değildir, yani aynı kaynaklara yönelik birden çok DELETE
istek aynı sonucu verir, ancak istek kaynağın durumunu etkiler. bir ve URI'sine sahip bir HttpClient
HTTP DELETE
isteğinde bulunmak için yöntemini kullanınHttpClient.DeleteAsync:
static async Task DeleteAsync(HttpClient httpClient)
{
using HttpResponseMessage response = await httpClient.DeleteAsync("todos/1");
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
var jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{jsonResponse}\n");
// Expected output
// DELETE https://jsonplaceholder.typicode.com/todos/1 HTTP/1.1
// {}
}
Yukarıdaki kod:
- adresine
"https://jsonplaceholder.typicode.com/todos/1"
birDELETE
istekte bulunur. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını konsola yazar.
İpucu
bir DELETE
isteğe yanıt (tıpkı bir PUT
istek gibi) bir gövde içerebilir veya içermeyebilir.
HTTP Başlığı
İstek HEAD
bir isteğe benzer GET
. Kaynağı döndürmek yerine yalnızca kaynakla ilişkili üst bilgileri döndürür. İstek yanıtı HEAD
bir gövde döndürmez. bir ve URI'sine sahip bir HttpClient
HTTP HEAD
isteğinde bulunmak için olarak ayarlanmış HttpMethod.Head
yöntemi HttpMethod kullanınHttpClient.SendAsync:
static async Task HeadAsync(HttpClient httpClient)
{
using HttpRequestMessage request = new(
HttpMethod.Head,
"https://www.example.com");
using HttpResponseMessage response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
foreach (var header in response.Headers)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}
Console.WriteLine();
// Expected output:
// HEAD https://www.example.com/ HTTP/1.1
// Accept-Ranges: bytes
// Age: 550374
// Cache-Control: max-age=604800
// Date: Wed, 10 Aug 2022 17:24:55 GMT
// ETag: "3147526947"
// Server: ECS, (cha / 80E2)
// X-Cache: HIT
}
Yukarıdaki kod:
- adresine
"https://www.example.com/"
birHEAD
istekte bulunur. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını konsola yazar.
- Tüm yanıt üst bilgilerini yineler ve her birini konsola yazar.
HTTP Seçenekleri
İstek OPTIONS
, bir sunucunun veya uç noktanın hangi HTTP yöntemlerini desteklediğini belirlemek için kullanılır. bir ve URI'sine sahip bir HttpClient
HTTP OPTIONS
isteğinde bulunmak için olarak ayarlanmış HttpMethod.Options
yöntemi HttpMethod kullanınHttpClient.SendAsync:
static async Task OptionsAsync(HttpClient httpClient)
{
using HttpRequestMessage request = new(
HttpMethod.Options,
"https://www.example.com");
using HttpResponseMessage response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode()
.WriteRequestToConsole();
foreach (var header in response.Content.Headers)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}
Console.WriteLine();
// Expected output
// OPTIONS https://www.example.com/ HTTP/1.1
// Allow: OPTIONS, GET, HEAD, POST
// Content-Type: text/html; charset=utf-8
// Expires: Wed, 17 Aug 2022 17:28:42 GMT
// Content-Length: 0
}
Yukarıdaki kod:
- adresine
"https://www.example.com/"
birOPTIONS
HTTP isteği gönderir. - Yanıtın başarılı olmasını sağlar ve istek ayrıntılarını konsola yazar.
- Tüm yanıt içeriği üst bilgilerini yineler ve her birini konsola yazar.
HTTP İzleme
İstek TRACE
, istek iletisinde uygulama düzeyinde geri döngü sağladığından hata ayıklama için yararlı olabilir. HTTP TRACE
isteğinde bulunmak için kullanarak bir HttpRequestMessage HttpMethod.Trace
oluşturun:
using HttpRequestMessage request = new(
HttpMethod.Trace,
"{ValidRequestUri}");
Dikkat
TRACE
HTTP yöntemi tüm HTTP sunucuları tarafından desteklenmez. Akıllıca kullanılmasa bir güvenlik açığı ortaya çıkarabilir. Daha fazla bilgi için bkz . Open Web Application Security Project (OWASP): Siteler Arası İzleme.
HTTP yanıtını işleme
Bir HTTP yanıtını her işlerken türüyle etkileşim kurarsınız HttpResponseMessage . Yanıtın geçerliliği değerlendirilirken birkaç üye kullanılır. HTTP durum kodu özelliği aracılığıyla HttpResponseMessage.StatusCode kullanılabilir. İstemci örneği için bir istek gönderdiğinizi düşünün:
using HttpResponseMessage response = await httpClient.SendAsync(request);
değerinin response
OK
(HTTP durum kodu 200) olduğundan emin olmak için, aşağıdaki örnekte gösterildiği gibi değerlendirebilirsiniz:
if (response is { StatusCode: HttpStatusCode.OK })
{
// Omitted for brevity...
}
Başarılı bir yanıtı temsil eden (HTTP durum kodu 201), (HTTP durum kodu 202 NO CONTENT
), ACCEPTED
(HTTP durum kodu 204) ve RESET CONTENT
(HTTP durum kodu 205) gibi CREATED
başka HTTP durum kodları da vardır. Bu kodları değerlendirmek için özelliğini de kullanabilirsiniz HttpResponseMessage.IsSuccessStatusCode ve bu da yanıt durum kodunun 200-299 aralığında olmasını sağlar:
if (response.IsSuccessStatusCode)
{
// Omitted for brevity...
}
Çerçevenin HttpRequestExceptionoluşturması gerekiyorsa yöntemini çağırabilirsiniz HttpResponseMessage.EnsureSuccessStatusCode() :
response.EnsureSuccessStatusCode();
Bu kod, yanıt durum kodu 200-299 aralığında değilse bir HttpRequestException
oluşturur.
HTTP geçerli içerik yanıtları
Geçerli bir yanıtla, özelliğini kullanarak yanıt gövdesine Content erişebilirsiniz. Gövde, akış HttpContent , bayt dizisi veya dize olarak gövdeye erişmek için kullanabileceğiniz bir örnek olarak kullanılabilir:
await using Stream responseStream =
await response.Content.ReadAsStreamAsync();
Yukarıdaki kodda, responseStream
yanıt gövdesini okumak için kullanılabilir.
byte[] responseByteArray = await response.Content.ReadAsByteArrayAsync();
Yukarıdaki kodda, responseByteArray
yanıt gövdesini okumak için kullanılabilir.
string responseString = await response.Content.ReadAsStringAsync();
Yukarıdaki kodda, responseString
yanıt gövdesini okumak için kullanılabilir.
Son olarak, bir HTTP uç noktasının JSON döndürdüğünden emin olduğunuzda System.Net.Http.Json NuGet paketini kullanarak yanıt gövdesini geçerli bir C# nesnesine seri durumdan çıkarabilirsiniz:
T? result = await response.Content.ReadFromJsonAsync<T>();
Yukarıdaki kodda, result
yanıt gövdesi türü T
olarak seri durumdan çıkarılır.
HTTP hata işleme
BIR HTTP isteği başarısız olduğunda, HttpRequestException oluşturulur. İşlemeyi göz önünde bulundurmanız gerekebilecek başka olası özel durumlar da olduğundan, bu özel durumun tek başına yakalanması yeterli olmayabilir. Örneğin, çağıran kod istek tamamlanmadan önce iptal edilmiş bir iptal belirteci kullanmış olabilir. Bu senaryoda, öğesini yakalarsınız TaskCanceledException:
using var cts = new CancellationTokenSource();
try
{
// Assuming:
// httpClient.Timeout = TimeSpan.FromSeconds(10)
using var response = await httpClient.GetAsync(
"http://localhost:5001/sleepFor?seconds=100", cts.Token);
}
catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
{
// When the token has been canceled, it is not a timeout.
Console.WriteLine($"Canceled: {ex.Message}");
}
Benzer şekilde, HTTP isteğinde bulunurken, sunucu aşılana kadar HttpClient.Timeout yanıt vermezse aynı özel durum oluşturulur. Ancak bu senaryoda, zaman aşımının oluştuğundan, öğesini yakalarken TaskCanceledExceptionöğesini Exception.InnerException değerlendirerek ayırt edebilirsiniz:
try
{
// Assuming:
// httpClient.Timeout = TimeSpan.FromSeconds(10)
using var response = await httpClient.GetAsync(
"http://localhost:5001/sleepFor?seconds=100");
}
catch (OperationCanceledException ex) when (ex.InnerException is TimeoutException tex)
{
Console.WriteLine($"Timed out: {ex.Message}, {tex.Message}");
}
Yukarıdaki kodda, iç özel durum zaman TimeoutException aşımı oluştuğunda ve istek iptal belirteci tarafından iptal edilmediğinde.
Bir HttpRequestExceptionyakalama sırasında HTTP durum kodunu değerlendirmek için özelliğini değerlendirebilirsiniz HttpRequestException.StatusCode :
try
{
// Assuming:
// httpClient.Timeout = TimeSpan.FromSeconds(10)
using var response = await httpClient.GetAsync(
"http://localhost:5001/doesNotExist");
response.EnsureSuccessStatusCode();
}
catch (HttpRequestException ex) when (ex is { StatusCode: HttpStatusCode.NotFound })
{
// Handle 404
Console.WriteLine($"Not found: {ex.Message}");
}
Yukarıdaki kodda EnsureSuccessStatusCode() , yanıt başarılı olmazsa bir özel durum oluşturma yöntemi çağrılır. Ardından, yanıtın HttpRequestException.StatusCode bir 404
(HTTP durum kodu 404) olup olmadığını belirlemek için özelliği değerlendirilir. Sizin adınıza örtük olarak çağıran EnsureSuccessStatusCode
birkaç yardımcı yöntem HttpClient
vardır, aşağıdaki API'leri göz önünde bulundurun:
İpucu
Sizin adınıza örtük bir HttpResponseMessage
çağrı EnsureSuccessStatusCode
döndürmeyen HTTP isteklerinde bulunmak için kullanılan tüm HttpClient
yöntemler.
Bu yöntemleri çağırırken, yanıtın HttpRequestException
HTTP durum kodunu belirlemek için ve özelliğini işleyebilirsiniz HttpRequestException.StatusCode :
try
{
// These extension methods will throw HttpRequestException
// with StatusCode set when the HTTP request status code isn't 2xx:
//
// GetByteArrayAsync
// GetStreamAsync
// GetStringAsync
using var stream = await httpClient.GetStreamAsync(
"https://localhost:5001/doesNotExists");
}
catch (HttpRequestException ex) when (ex is { StatusCode: HttpStatusCode.NotFound })
{
// Handle 404
Console.WriteLine($"Not found: {ex.Message}");
}
kodunuz içinde oluşturmanız HttpRequestException gereken senaryolar olabilir. HttpRequestException() Oluşturucu geneldir ve özel bir iletiyle özel durum oluşturmak için bunu kullanabilirsiniz:
try
{
using var response = await httpClient.GetAsync(
"https://localhost:5001/doesNotExists");
// Throw for anything higher than 400.
if (response is { StatusCode: >= HttpStatusCode.BadRequest })
{
throw new HttpRequestException(
"Something went wrong", inner: null, response.StatusCode);
}
}
catch (HttpRequestException ex) when (ex is { StatusCode: HttpStatusCode.NotFound })
{
Console.WriteLine($"Not found: {ex.Message}");
}
HTTP proxy'si
HTTP proxy'si iki yoldan biriyle yapılandırılabilir. Özelliğinde HttpClient.DefaultProxy bir varsayılan belirtilir. Alternatif olarak, özelliğinde HttpClientHandler.Proxy bir proxy belirtebilirsiniz.
Genel varsayılan proxy
HttpClient.DefaultProxy
, oluşturucusunda açıkça HttpClientHandler hiçbir ara sunucu ayarlanmadıysa tüm HttpClient
örneklerin kullandığı varsayılan ara sunucuyu belirleyen statik bir özelliktir.
Bu özellik tarafından döndürülen varsayılan örnek, platformunuza bağlı olarak farklı bir kural kümesinden sonra başlatılır:
- Windows için: Ortam değişkenlerinden veya bunlar tanımlanmamışsa kullanıcının proxy ayarlarından ara sunucu yapılandırmasını okur.
- macOS için: Ortam değişkenlerinden veya tanımlanmamışsa sistemin proxy ayarlarından ara sunucu yapılandırmasını okur.
- Linux için: Ortam değişkenlerinden ara sunucu yapılandırmasını okur veya bunların tanımlanmaması durumunda, bu özellik tüm adresleri atlayan yapılandırılmamış bir örneği başlatır.
Windows ve Unix tabanlı platformlarda başlatma için DefaultProxy
kullanılan ortam değişkenleri şunlardır:
HTTP_PROXY
: HTTP isteklerinde kullanılan proxy sunucusu.HTTPS_PROXY
: HTTPS isteklerinde kullanılan proxy sunucusu.ALL_PROXY
: ve/veya tanımlanmadığı durumlardaHTTP_PROXY
HTTP ve/HTTPS_PROXY
veya HTTPS isteklerinde kullanılan proxy sunucusu.NO_PROXY
: Ara sunucu oluşturmanın dışında tutulması gereken ana bilgisayar adlarının virgülle ayrılmış listesi. Joker karakterler için yıldız işareti desteklenmez; bir alt etki alanıyla eşleştirmek istemeniz durumunda öndeki noktayı kullanın. Örnekler:NO_PROXY=.example.com
(baştaki noktayla) ile eşleşecektirwww.example.com
ancak eşleşmeyecektirexample.com
.NO_PROXY=example.com
(baştaki nokta olmadan) ile eşleşmezwww.example.com
. Bu davranış gelecekte diğer ekosistemleri daha iyi eşleştirmek için yeniden ziyaret edilebilir.
Ortam değişkenlerinin büyük/küçük harfe duyarlı olduğu sistemlerde değişken adlarının tümü küçük harf veya tümü büyük harf olabilir. Önce küçük harf adları denetleniyor.
Ara sunucu, isteğe bağlı olarak iki nokta üst üste ve bağlantı noktası numarasıyla izlenen bir ana bilgisayar adı veya IP adresi olabileceği gibi, isteğe bağlı olarak proxy kimlik doğrulaması için kullanıcı adı ve parola da dahil olmak üzere bir http
URL olabilir. URL, ile değil ile https
başlamalıdır http
ve konak adı, IP veya bağlantı noktasından sonra metin içeremez.
İstemci başına ara sunucu
özelliği, HttpClientHandler.Proxy İnternet kaynaklarına WebProxy yönelik istekleri işlemek için kullanılacak nesneyi tanımlar. Hiçbir proxy kullanılmaması gerektiğini belirtmek için özelliğini yöntemi tarafından döndürülen proxy örneğine GlobalProxySelection.GetEmptyWebProxy() ayarlayınProxy
.
Yerel bilgisayar veya uygulama yapılandırma dosyası varsayılan ara sunucunun kullanıldığını belirtebilir. Proxy özelliği belirtilirse, Proxy özelliğindeki proxy ayarları yerel bilgisayarı veya uygulama yapılandırma dosyasını geçersiz kılar ve işleyici belirtilen proxy ayarlarını kullanır. Yapılandırma dosyasında proxy belirtilmemişse ve Proxy özelliği belirtilmemişse, işleyici yerel bilgisayardan devralınan proxy ayarlarını kullanır. Ara sunucu ayarı yoksa istek doğrudan sunucuya gönderilir.
sınıfı, HttpClientHandler yerel bilgisayar ayarlarından devralınan joker karakterlerle ara sunucu atlama listesini ayrıştırır. Örneğin, HttpClientHandler
sınıfı tarayıcılardan atlama listesini "nt*"
normal ifadesi olarak ayrıştırıyor "nt.*"
. Bu nedenle url'si http://nt.com
sınıfını kullanarak proxy'yi atlar HttpClientHandler
.
HttpClientHandler
sınıfı yerel ara sunucu atlamasını destekler. Sınıfı, aşağıdaki koşullardan herhangi biri karşılanırsa hedefi yerel olarak kabul eder:
- Hedef düz bir ad içeriyor (URL'de nokta yok).
- Hedef bir geri döngü adresi (Loopback veya IPv6Loopback) içerir veya hedef yerel bilgisayara atanmış bir IPAddress adres içerir.
- Hedefin etki alanı soneki, yerel bilgisayarın etki alanı sonekiyle () eşleşirDomainName.
Ara sunucu yapılandırma hakkında daha fazla bilgi için bkz: