عميل HTTP بلغة C#: إجراء الطلبات بشكل صحيح من الألف إلى الياء
\n\nفي التطوير الحديث على منصة .NET، يعد العمل مع طلبات HTTP إحدى المهام الرئيسية. سواء كان ذلك التكامل مع REST API خارجي، أو إرسال البيانات إلى الخادم، أو تحميل صفحات الويب - فإن الاستخدام الصحيح لـ HttpClient في C# أمر بالغ الأهمية لأداء واستقرار التطبيق. في هذه المقالة، سنقوم بتحليل جميع جوانب العمل مع عميل HTTP في C#: من الأمثلة الأساسية إلى التقنيات المتقدمة، ومعالجة الأخطاء، وأفضل الممارسات.
1. أساسيات العمل مع HttpClient في C#
\n\nHttpClient هي الفئة الرئيسية في .NET لإرسال طلبات HTTP وتلقي الردود. وهي موجودة في مساحة الأسماء System.Net.Http ومتاحة بدءًا من .NET Framework 4.5 وجميع إصدارات .NET Core/.NET 5+.
قاعدة مهمة: HttpClient مصمم لإعادة الاستخدام. إنشاء مثيل جديد لكل طلب هو نمط معاكس (anti-pattern) يمكن أن يؤدي إلى استنزاف المقابس (socket exhaustion). بدلاً من ذلك، استخدم مثيلًا ثابتًا واحدًا أو مثيل singleton.
مثال أساسي لطلب GET:
\n\nusing System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nclass Program\n{\n private static readonly HttpClient client = new HttpClient();\n\n static async Task Main(string[] args)\n {\n try\n {\n HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");\n response.EnsureSuccessStatusCode();\n string responseBody = await response.Content.ReadAsStringAsync();\n Console.WriteLine(responseBody);\n }\n catch (HttpRequestException e)\n {\n Console.WriteLine($"خطأ في الطلب: {e.Message}");\n }\n }\n}\n\nفي هذا المثال، نقوم بإنشاء HttpClient ثابت، وإرسال طلب GET، والتحقق من نجاح الرد باستخدام EnsureSuccessStatusCode()، وقراءة نص الرد كسلسلة نصية.
2. أنواع طلبات HTTP والعمل مع الرؤوس (Headers)
\n\nبالإضافة إلى GET، يدعم HttpClient جميع طرق HTTP الأساسية: POST، PUT، DELETE، PATCH وغيرها. دعنا نلقي نظرة على إرسال طلب POST مع بيانات JSON - هذا هو السيناريو الأكثر شيوعًا عند العمل مع REST API.
مثال لطلب POST مع JSON:
\n\nusing System;\nusing System.Net.Http;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\n\nclass Program\n{\n private static readonly HttpClient client = new HttpClient();\n\n static async Task Main(string[] args)\n {\n var data = new { Name = "John", Age = 30 };\n string json = JsonSerializer.Serialize(data);\n var content = new StringContent(json, Encoding.UTF8, "application/json");\n\n try\n {\n HttpResponseMessage response = await client.PostAsync("https://api.example.com/users", content);\n response.EnsureSuccessStatusCode();\n string result = await response.Content.ReadAsStringAsync();\n Console.WriteLine($"تم إنشاء المستخدم: {result}");\n }\n catch (HttpRequestException e)\n {\n Console.WriteLine($"خطأ: {e.Message}");\n }\n }\n}\n\nالعمل مع الرؤوس (Headers): غالبًا ما تتطلب واجهات API إرسال رموز المصادقة (tokens) أو رؤوس أخرى. يمكن إضافتها بطريقتين:
\n\n- \n
- بشكل عام (Globally) - من خلال الخاصية
DefaultRequestHeaders(لجميع طلبات العميل). \n - بشكل محلي (Locally) - من خلال مجموعة
Headersفي كائنHttpRequestMessage(لطلب معين). \n
مثال على إضافة رأس Authorization:
\n\n// بشكل عام\nclient.DefaultRequestHeaders.Authorization = \n new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your-token");\n\n// بشكل محلي\nvar request = new HttpR