لماذا يكسر Path.Combine عناوين URL وكيفية إصلاح ذلك؟
تخيل: أنت تكتب تطبيقًا بلغة C# يتصل بواجهة برمجة تطبيقات (API). تحتاج إلى تجميع عنوان URL مثل https://api.example.com/v1/users/123. أول ما يتبادر إلى الذهن هو استخدام Path.Combine المألوف. وهذا خطأ يرتكبه آلاف المطورين. سؤال «Path.Combine for URLs؟» على Stack Overflow حصد مئات الآلاف من المشاهدات - وليس من دون سبب.
في هذه المقالة، سنشرح لماذا يعتبر Path.Combine خطيرًا جدًا على عناوين URL، وسنعرض 4 طرق صحيحة للصق العناوين في C#. ستتعلم كيف يعمل UriBuilder، ولماذا يجب الانتباه إلى مكتبة Flurl، وكيفية كتابة طريقتك الآمنة لدمج عناوين URL. هيا بنا!
المشكلة: ما الخطأ في Path.Combine؟
طريقة Path.Combine صُممت لأنظمة ملفات Windows. تستخدم الشرطة المائلة العكسية (\\) وتراعي خصائص الأقراص (مثل C:\\). أما عنوان URL فيعمل بالشرطة المائلة الأمامية (/) وليس لديه مفهوم «القرص». لنلق نظرة على مثال:
string baseUrl = "https://api.example.com/api";string endpoint = "/users/123";string result = Path.Combine(baseUrl, endpoint);Console.WriteLine(result);// الإخراج: https:\\\\api.example.com\\api\\users\\123 (على Windows)// أو أسوأ: https://api.example.com/api/users/123 (إذا كنت محظوظًا)النتيجة، بعبارة ملطفة، غير صالحة. Path.Combine يستبدل الشرط المائلة الأمامية بشرط مائلة عكسية (في Windows)، وسيفشل طلب HTTP الخاص بك مع خطأ. حتى لو بدا كل شيء طبيعيًا على Linux، يصبح الكود غير قابل للنقل. وإذا كان عنوان URL الأساسي يحتوي بالفعل على شرطة مائلة في النهاية؟ أو إذا كان في نقطة النهاية شرطة مائلة مزدوجة؟ تبدأ الفوضى.
مثال حقيقي من Stack Overflow
أحد أكثر الإجابات شيوعًا على سؤال «Path.Combine for URLs؟» (المؤلف — Brian، أكثر من 600 صوت إيجابي) يبدأ بعبارة: «من فضلك، لا تفعل هذا. Path.Combine للملفات، وليس لعناوين URL». وهذه قاعدة ذهبية. دعنا نتعرف على الأدوات التي تقدمها C# للعمل الآمن مع عناوين URL.
الطريقة 1: Uri.TryCreate — طريقة .NET المدمجة
الطريقة الأولى والأكثر وضوحًا هي استخدام الفئة Uri. إنها تعرف كيفية دمج عنوان URL الأساسي والمسار النسبي بشكل صحيح:
string baseUrl = "https://api.example.com/api";string relativePath = "/users/123";
if (Uri.TryCreate(baseUrl, relativePath, out Uri result)){ Console.WriteLine(result.ToString()); // الإخراج: https://api.example.com/users/123}else{ Console.WriteLine("عنوان URL غير صحيح");}هام: الوسيطة الثانية لـ TryCreate يجب أن تكون URI نسبيًا (يبدأ بـ /). إذا مررت فقط "users/123"، فسيتم تفسيره على أنه مطلق - وستكون النتيجة غير صحيحة. هذه ليست الطريقة الأكثر مرونة، ولكنها حل مدمج ممتاز للحالات البسيطة.
الطريقة 2: UriBuilder — قوي ومرن
الفئة UriBuilder تمنحك تحكمًا كاملاً في كل جزء من عنوان URL: المخطط، المضيف، المنفذ، المسار ومعلمات الاستعلام. هذا هو الخيار المثالي عندما تحتاج إلى تجميع عنوان معقد:
var builder = new UriBuilder("https://api.example.com");builder.Port = 8080;builder.Path = "/api/v1/users";builder.Query = "page=1&limit=10";
Uri uri = builder.Uri;Console.WriteLine(uri.ToString());// الإخراج: https://api.example.com:8080/api/v1/users?page=1&limit=10لماذا هذا رائع؟
- التهريب التلقائي — سيتم ترميز الأحرف الخاصة في معلمات الاستعلام.
- الشرط المائلة الصحيحة —
UriBuilderيضيف أو يزيل الشرط المائلة الزائدة بنفسه. - المنافذ والمخططات — سهولة تغيير http إلى https أو إضافة منفذ.
لكن هناك فارق بسيط: Path
المدونات
توصيات الكتب
اقرأ أيضًا
التصميم القائم على المجال في Kotlin: كيف لا تغرق في تعقيد منطق الأعمال
حقن التبعيات (Dependency Injection) في TypeScript: دليل شامل
كيفية كتابة REST API بلغة Java في 30 دقيقة: دليل خطوة بخطوة
كود C# النظيف: كيف تكتبه دون خجل من عرضه على زملائك
Go في الشركات الناشئة: كيف ساعدت لغة Google في بناء شركات بمليارات الدولارات