JSON في C# dynamic في 2025: إلغاء التسلسل بدون ألم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

JSON و C# dynamic: لماذا لا يزال هذا ألمًا (وكيفية علاجه)

\n\n

هل سبق لك أن نظرت إلى استجابة JSON من API وفكرت: "يا إلهي، لماذا أنت معقد جدًا؟" خاصة إذا كان هيكل البيانات يتغير في كل مرة مثل الطقس في سانت بطرسبرغ. المثال الكلاسيكي هو الرد من خدمة خارجية حيث يمكن أن تكون الحقول إما سلاسل نصية أو مصفوفات أو حتى null. أو عندما تحتاج إلى تحليل JSON بسرعة، ولكن إنشاء فئة منفصلة له يشبه استخدام مجهر لقطع شريحة إلكترونية.

\n\n

بالضبط لمثل هذه الحالات، يوجد السحر dynamic في C#. سؤال "Deserialize JSON into C# dynamic object؟" على Stack Overflow حصد آلاف المشاهدات - وهذا ليس من قبيل الصدفة. في عام 2025، عندما أصبحت الخدمات المصغرة وواجهات برمجة التطبيقات الديناميكية هي القاعدة، فإن القدرة على العمل مع JSON بسرعة ومرونة هي قوة خارقة للمطور.

\n\n

في هذه المقالة، سنستعرض أفضل الممارسات لإلغاء تسلسل JSON إلى كائن dynamic في C#. بدون نظرية مملة، فقط كود وأمثلة ونصائح عملية. هيا بنا!

\n\n

لماذا dynamic؟ وليس فقط JObject؟

\n\n

سؤال جيد. في C#، يوجد JObject (من Newtonsoft.Json) و JsonDocument (من System.Text.Json). كلاهما يمكنه تحليل JSON "أثناء التنقل". لكن dynamic يعطي شيئًا مهمًا واحدًا - السكر النحوي.

\n\n

قارن:

\n\n
// عبر JObject\nvar json = JObject.Parse(rawJson);\nvar name = (string)json["user"]["name"];\n\n// عبر dynamic\ndynamic obj = JsonConvert.DeserializeObject<dynamic>(rawJson);\nvar name = obj.user.name;\n
\n\n

الخيار الثاني يُقرأ ككود عادي، وليس كـ "احصل على المفتاح، حوّل النوع، تحقق من null". هذا مفيد بشكل خاص عندما يكون JSON متداخلاً بعمق.

\n\n

الطريقة 1: الكلاسيكية - Newtonsoft.Json (Json.NET)

\n\n

نعم، نحن في عام 2025، لكن Newtonsoft.Json لا يزال حيًا وبصحة جيدة. العديد من المشاريع القديمة، وحتى بعض الحديثة، تستخدمه. لماذا؟ المرونة وقابلية التوسع وملايين الإعدادات.

\n\n

مثال أساسي

\n\n
using Newtonsoft.Json;\n\nstring json = @"\n{\n    'name': 'أليكسي',\n    'age': 30,\n    'skills': ['C#', 'Python', 'SQL'],\n    'address': {\n        'city': 'موسكو',\n        'zip': 101000\n    }\n}";\n\ndynamic obj = JsonConvert.DeserializeObject<dynamic>(json);\n\nConsole.WriteLine(obj.name);        // أليكسي\nConsole.WriteLine(obj.age);         // 30\nConsole.WriteLine(obj.skills[0]);   // C#\nConsole.WriteLine(obj.address.city); // موسكو\n
\n\n

كل شيء بسيط وأنيق. لكن هناك فارق بسيط: عند العمل مع dynamic، تفقد IntelliSense والتحقق من الأنواع في وقت الترجمة. الخطأ في اسم الحقل سيظهر فقط في وقت التشغيل. لذلك:

\n\n
    \n
  • استخدم dynamic فقط لقراءة البيانات التي لا تتحكم فيها.
  • \n
  • احرص دائمًا على تغليف الاستدعاءات في try-catch.
  • \n
  • لا تفرط في الاستخدام - إذا كان هيكل JSON مستقرًا، فمن الأفضل إنشاء فئة DTO.
  • \n
\n\n

الطريقة 2: الحديثة - System.Text.Json

\n\n

بدءًا من .NET Core 3.0، تروج Microsoft لـ System.Text.Json - سريع، أصلي، بدون تبعيات خارجية. في عام 2025، هذا هو المعيار للمشاريع الجديدة.

\n\n

لكن هناك مشكلة: System.Text.Json لا يعرف كيفية إلغاء التسلسل إلى dynamic "خارج الصندوق". ستحتاج إلى القليل من الحيلة.

\n\n

الخيار A: عبر JsonDocument و ExpandoObject

\n\n
using System.Text.Json;\nusing System.Dynamic;\n\nstring json = @"{""name"":""إيلينا"",""age"":25,""active"":true}";\n\nusing JsonDocument doc = JsonDocument.Parse(json);\ndynamic obj = ConvertToExpando(doc.RootElement);\n\nConsole.WriteLine(obj.name);   // إيلينا\nConsole.WriteLine(obj.age);    // 25\nConsole.WriteLine(obj.active); // True\n\nstatic ExpandoObject ConvertToExpando(JsonElement element)\n{\n    var expando = new ExpandoObject();\n    var dict = (IDictionary<string, object>)expando;\n\n    foreach (var property in element.Enumera                

المدونات

توصيات الكتب