البرمجة وتطوير البرمجيات

كيفية استخدام unions والتسلسلات المغلقة في ASP.NET Core

يوضح .NET Blog كيفية توظيف أنواع unions والتسلسلات الهرمية المغلقة مع System.Text.Json عبر Minimal APIs وMVC وSignalR وBlazor وOpenAPI. كما يحدد حالات الالتباس ومصادر الربط التي لا تدعم هذه الأنواع.

10 سبتمبر 2026
4 دقائق قراءة
215 قراءة
certi.news Editorial Team
كيفية استخدام unions والتسلسلات المغلقة في ASP.NET Core

يقدم ASP.NET Core في .NET 11 دعماً عملياً لاستخدام أنواع union والتسلسلات الهرمية المغلقة مع System.Text.Json، بما يسمح بتمثيل قيمة يمكن أن تنتمي إلى أكثر من نوع أو عائلة محددة من الأنواع. ويمتد هذا الدعم إلى Minimal APIs ووحدات تحكم MVC وSignalR وBlazor ووثائق OpenAPI، مع اختلافات مهمة في طريقة القراءة والكتابة وحدود ربط المعلمات.

متى يكون union مناسباً؟

يناسب union العقود التي تقبل بدائل مستقلة من دون الحاجة إلى غلاف JSON أو حقل discriminator. ومن أمثلة ذلك قيمة يمكن أن تكون رقماً صحيحاً أو سلسلة نصية، أو إعداداً يقبل قيمة منطقية أو كائناً يضم خيارات أكثر تفصيلاً. عند التسلسل، تُكتب الحالة النشطة مباشرة بصيغتها الطبيعية؛ فلا يضاف غلاف خاص بنوع union ولا discriminator.

تُسلسل الحالات التي يمكن تمييزها بوضوح من بنية JSON تلقائياً. لكن إذا تشاركت الحالات البنية نفسها، مثل union يضم كائنَي Cat وDog، فلن يستطيع System.Text.Json تحديد النوع من رمز JSON وحده. في هذه الحالة يمكن توفير JsonTypeClassifier مخصص لاختيار الحالة الصحيحة. وينطبق الأمر ذاته على بعض عقود الطلبات التي تقبل رقماً أو سلسلة، إذ تسمح إعدادات JSON الخاصة بالويب بقراءة الأرقام من السلاسل، ما قد يجعل النص قابلاً للتفسير بوصفه أيّاً من الحالتين.

التسلسلات الهرمية المغلقة تختلف عن union

لا يعني استخدام المعدّل closed أن التسلسل متعدد الأشكال سيُفعّل تلقائياً. فعند التعامل مع نوع مشتق ملموس مثل PaymentAuthorized، يتعامل System.Text.Json معه كأي نوع آخر، ويُنتج JSON يتضمن paymentId وamount من دون discriminator.

أما عند استخدام النوع الأساسي PaymentEvent في واجهة API، فيلزم تحديد النوع المشتق الذي يجب إنشاؤه. ويمكن تفعيل ذلك على النوع الأساسي باستخدام JsonPolymorphic(InferClosedTypePolymorphism = true)، أو عبر JsonSerializerOptions.InferClosedTypePolymorphism. عندها يستنتج System.Text.Json الأنواع المشتقة في التسلسل المغلق ويستخدم أسماءها كمعرّفات، مثل $type بقيمة PaymentAuthorized.

الاختيار بين النموذجين يعتمد على طبيعة العقد: يمثل union بدائل قد لا تنتمي إلى عائلة واحدة، بينما تلائم التسلسلات المغلقة مجموعة مترابطة من الأحداث أو الكيانات تحتاج إلى discriminator واضح.

الدعم عبر طبقات ASP.NET Core

في Minimal APIs، يمكن استخدام union كمعلمة لجسم الطلب أو كنوع للإرجاع، سواء في المسار التنفيذي المعتاد أو عبر Request Delegate Generator، مع سلوك متماثل بين المسارين. كما يمكن أن يظهر union داخل نموذج آخر، أو كعنصر في IAsyncEnumerable، أو ضمن حاوية تستخدم AsParameters، وتظل إعدادات ConfigureHttpJsonOptions مؤثرة في التسلسل.

وتدعم وحدات تحكم MVC unions كمعلمات للإجراءات وأنواع للإرجاع، بما في ذلك Task<TUnion> وValueTask<TUnion>. وبما أن MVC يستخدم إعدادات JsonSerializerDefaults.Web، فإن مشكلة الالتباس بين الرقم والسلسلة في مدخلات HTTP تنطبق عليه أيضاً.

في SignalR، يعمل الدعم عبر JsonHubProtocol للمعلمات وقيم الإرجاع وعناصر التدفق. ولا يحتاج union من نوع int أو string إلى classifier عند استخدام هذا البروتوكول، لأن JsonHubProtocol لا يعامل رمز JSON النصي بوصفه ملتبساً في هذه الحالة. لكن unions التي تتشارك الحالات فيها رمز StartObject، مثل UnionPet(Cat, Dog)، تظل بحاجة إلى classifier. ولا يدعم SignalR هذه الوظيفة عند استخدام MessagePack أو Newtonsoft.Json hub protocols.

Blazor وOpenAPI

تعمل معلمات مكونات Blazor داخل العملية عبر إسناد مباشر، ولذلك لا تحتاج إلى تسلسل. لكن JavaScript interop وحالة المكونات المحفوظة والمعلمات أثناء prerendering تمر عبر System.Text.Json، فتتبع قواعد unions نفسها. ويمكن مثلاً تمرير union إلى JavaScript بصيغة Boolean أو كائن خيارات، وفق الحالة النشطة، من دون إضافة غلاف أو discriminator.

في OpenAPI، يُمثّل union باستخدام مخطط anyOf يضم نوعاً لكل حالة. وتعيد الحالات استخدام أسماء مكونات Cat وDog نفسها عند ظهورها كأنواع مستقلة. ويختلف ذلك عن الأنواع متعددة الأشكال التي تحمل discriminator وتُرفع مخططاتها بأسماء مميزة. كما يمكن لـ ApiExplorer تمثيل عدة أنواع استجابة لنفس رمز الحالة ونوع المحتوى ضمن anyOf.

القيود التي يجب مراعاتها

يعتمد دعم unions على System.Text.Json، ولذلك لا يعمل مع مصادر الربط التي لا تمر عبر تحليل JSON. وتشمل هذه المصادر قيم query string وقيم المسارات والرؤوس وحقول النماذج. فقيمة مثل ?id=42 لا تكفي لتحديد ما إذا كان المقصود int أو string أو Guid. وينطبق القيد في Blazor على [SupplyParameterFromQuery] والربط من النماذج باستخدام [SupplyParameterFromForm]. ويشير المصدر إلى أن ربط union من هذه المصادر ما زال موضع دراسة وجمع ملاحظات.

القراءة التحريرية: القيمة الأساسية هنا ليست إضافة صيغة جديدة للـJSON، بل توحيد التعامل مع عقود متعددة الحالات عبر أجزاء واسعة من منظومة .NET 11. غير أن نجاح التصميم يتوقف على قابلية الحالات للتمييز وعلى مصدر البيانات؛ لذلك ينبغي تحديد classifier أو discriminator مبكراً، وعدم افتراض أن دعم التسلسل يعني دعم كل طرق ربط المعلمات.

مصدر الخبر
كيف أعددنا هذا الخبر؟

اعتمد الخبر على المصدر الأصلي الموضح أعلاه. قد نستخدم أدوات آلية للمساعدة في الاستخراج والتصنيف والصياغة، لكن النشر يخضع لقواعد تمنع المحتوى المكرر والقصير أو الروتيني منخفض القيمة. اقرأ سياستنا التحريرية.

c
كاتب المقال

certi.news Editorial Team

certi.news Editorial Team

The certi.news editorial team monitors technical sources and reconstructs news, verifying facts and context prior to publication.

ما الذي تحتاج معرفته

يضيف .NET 11 دعماً عملياً لاستخدام unions والتسلسلات الهرمية المغلقة مع System.Text.Json عبر طبقات متعددة من ASP.NET Core. يعتمد نجاح الاستخدام على إمكانية تمييز الحالات، كما أن هذا الدعم لا يمتد تلقائياً إلى ربط قيم query string والمسارات والرؤوس وحقول النماذج.

  • يمثل union قيمة يمكن أن تنتمي إلى بدائل مستقلة، وتُسلسل الحالة النشطة مباشرة من دون غلاف JSON أو discriminator.
  • إذا كانت حالات union متشابهة في بنية JSON، مثل Cat وDog، فقد يلزم توفير JsonTypeClassifier مخصص.
  • تحتاج التسلسلات الهرمية المغلقة إلى تفعيل الاستدلال متعدد الأشكال عند استخدام النوع الأساسي، ويمكن أن تستخدم أسماء الأنواع كمعرّفات مثل $type.
  • يشمل الدعم Minimal APIs وMVC وSignalR وBlazor وOpenAPI، مع اختلافات في البروتوكولات وسلوك الربط.
  • يمثل OpenAPI union باستخدام anyOf، بينما لا تعمل unions مع مصادر الربط التي لا تمر عبر تحليل JSON، مثل query string والمسارات والرؤوس وحقول النماذج.
  • لا يدعم SignalR هذه الوظيفة عند استخدام MessagePack أو بروتوكولات hub المعتمدة على Newtonsoft.Json.

أسئلة شائعة

متى يكون استخدام union مناسباً؟

يكون مناسباً عندما يقبل العقد بدائل مستقلة، مثل قيمة يمكن أن تكون رقماً صحيحاً أو سلسلة نصية، من دون الحاجة إلى غلاف JSON أو discriminator.

هل تُفعّل التسلسلات الهرمية المغلقة التعددية الأشكال تلقائياً؟

لا. يجب تفعيلها على النوع الأساسي باستخدام JsonPolymorphic(InferClosedTypePolymorphism = true) أو عبر JsonSerializerOptions.InferClosedTypePolymorphism.

هل يمكن استخدام unions مع قيم query string أو المسارات؟

لا يدعم المقال حالياً ربط unions من query string أو قيم المسارات أو الرؤوس أو حقول النماذج، لأن هذه المصادر لا تمر عبر تحليل JSON.

كيف يمثل OpenAPI أنواع union؟

يمثلها باستخدام مخطط anyOf يضم نوعاً لكل حالة.

من نفس التصنيف

مقالات قد تهمك

عرض كل الأخبار