إذا كنت تقرأ هذا المقال ، فمن المرجح أنك على دراية بماهية JSON وأن الصورة أدناه مألوفة بالنسبة لك. ولكن على أي حال ، أنصحك بزيارة هذه
الصفحة إذا لم تكن هناك من قبل ، وكذلك قبل قراءتها ، من المستحسن أن تتعرف على المبادئ العامة للعمل مع تدوين JSON في C # ، على سبيل المثال ،
على هذا الرابط .
أريد أن أشير إلى أن هذه الملاحظة لا تتظاهر بأنها أي كشف كامل للموضوع. الغرض من هذا النص هو تنظيم والحفاظ على تلك التطورات التي استخدمتها عند العمل مع مكتبة Newtonsoft.Json.بيان المشكلة
على العموم ، في إطار المقالة ، ليس من المهم للغاية كيفية الحصول على البيانات الأولية للتحليل ، ومع ذلك ، فإن هذا التفسير سوف يسهل بالتأكيد إدراك المادة. لذلك ، فإن المهمة الرئيسية هي تنفيذ وظائف واجهة برمجة تطبيقات
EXMO cryptoexchange . من أجل البساطة ، سنعمل بشكل أساسي مع الواجهة العامة (API العامة). في هذه الحالة ، سيبدو طلب المعلومات بمثابة عنوان صفحة عادي للموقع. لإرسال الطلبات ، يتم استخدام فئة HttpClient لمساحة الاسم System.Net.Http:
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync();
يمكن رؤية نتيجة هذا البرنامج من خلال النقر على الرابط
https://api.exmo.com/v1/trades/؟pair=BTC_USD . إذا قمت بتحميل هذه البيانات في
JSON C # Class Generator ، فسنقدم لك بنية الفصل التالية لإزالة التسلسل:
public class BTCUSD { public int trade_id { get; set; } public string type { get; set; } public string quantity { get; set; } public string price { get; set; } public string amount { get; set; } public int date { get; set; } } public class RootObject { public List<BTCUSD> BTC_USD { get; set; } }
تجدر الإشارة إلى أن وظيفة "الصفقات" لتبادل التشفير نفسها تسمح لك بطلب المعلومات على عدة أزواج من العملات في وقت واحد. وفي حالة الطلب
string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD";
ستبدو بنية الفصل بالفعل كالتالي:
public class BTCUSD { public int trade_id { get; set; } public string type { get; set; } public string quantity { get; set; } public string price { get; set; } public string amount { get; set; } public int date { get; set; } } public class ETHUSD { public int trade_id { get; set; } public string type { get; set; } public string quantity { get; set; } public string price { get; set; } public string amount { get; set; } public int date { get; set; } } public class RootObject { public List<BTCUSD> BTC_USD { get; set; } public List<ETHUSD> ETH_USD { get; set; } }
من الواضح ، لا يمكنك إعداد فصول لكل مجموعة من أزواج العملات ، مما يعني أنك بحاجة إلى الخروج بطريقة أو بأخرى.
كيف نفعل ذلك ليست ضرورية.من المثير للدهشة ، أنه من المستحيل تقريبًا العثور على مقالات جيدة حول العمل مع تدوين JSON على الإنترنت باللغة الروسية. نتيجة لذلك ، فإن تطبيقات EXMO API التي يمكن العثور عليها على GitHub تحتوي بطريقة ما على معالجات مع بنية البيانات الأصلية باستخدام split s و trim s و ما شابه.
يجب أن أعترف أنني أيضًا اخترعت دراجة وأنفذت التحليل بمفردي. على الرغم من أن التعليمات البرمجية تعمل بشكل مطلق ، إلا أن هذا مثال رائع على كيفية قيامك بذلك.
LinkedList<OrderInform> loi = new LinkedList<OrderInform>(); try { string[] json = answer.Split(new char[] { '{', '}' }); foreach (var item in json) { if (item.Length > 20) { string[] trade = item.Split(new char[] { ',' }); if (trade.Length > 5) { string t_id = trade[0].Split(new char[] { ':' })[1].Trim('"'); string t_type = trade[1].Split(new char[] { ':' })[1].Trim('"'); string t_quantity = trade[2].Split(new char[] { ':' })[1].Trim('"') .Replace(".", ","); string t_price = trade[3].Split(new char[] { ':' })[1].Trim('"') .Replace(".", ","); string t_amount = trade[4].Split(new char[] { ':' })[1].Trim('"') .Replace(".", ","); string t_date_time = trade[5].Split(new char[] { ':' })[1].Trim('"'); loi.AddLast(new OrderInform(pair, Convert.ToInt32(t_id), t_type, Convert.ToDouble(t_quantity), Convert.ToDouble(t_price), Convert.ToDouble(t_amount), (new DateTime(1970, 1, 1, 0, 0, 0, 0)) .AddSeconds(Convert.ToInt32(t_date_time)))); } } } return loi; } catch (Exception ex) { return new LinkedList<OrderInform>(); }
كائنات JSON (فئة JObject)
كائن JSON هو مجموعة غير مرتبة من أزواج المفتاح / القيمة. يبدأ الكائن بـ '{' (قوس مجعد مفتوح) وينتهي بـ '}' (قوس مجعد مغلق). يتبع كل اسم: (نقطتين) ، يتم فصل أزواج المفاتيح / القيمة بفاصلة.

من الهيكل المقترح لنا في وقت سابق من قبل JSON C # Class Generator ، نرى أنه لكل زوج عملات لدينا 6 حقول ثابتة. لفهم في فصل منفصل واطلق عليه الأمر.
class Order { public int trade_id { get; set; } public string type { get; set; } public double quantity { get; set; } public double price { get; set; } public double amount { get; set; } public int date { get; set; } }
لكي تتمكن من "الاستيلاء" على مجموعة من هذه الحقول من هيكل البيانات المتغير ديناميكيًا في البورصة ، يجب أن تفهم بمزيد من التفصيل أنواع البيانات المتاحة في مكتبة newtosoft.json. بشكل أكثر تحديدًا ، في مساحة الاسم newtonsoft.json.linq.
للعمل مع المكتبة ، يجب تثبيته.لتثبيت المكتبة في Visual Studio ، يمكنك ببساطة البحث في NuGet.
انقر بزر الماوس الأيمن على الحل في Solution Explorer وحدد "إدارة حزم NuGet للحل ..." (إدارة حزم NuGet للحل ... ").

بعد ذلك ، انقر فوق "استعراض" وأدخل newtosoft.json في شريط البحث. نضع علامة أمام الحل الخاص بنا وانقر فوق "تثبيت" ("تثبيت").

مساحة الاسم newtosoft.json.linq ، بعد تثبيت المكتبة ، تصبح متاحة للاتصال بالمشروع:
using Newtonsoft.Json.Linq;
يستخدم
Newtosoft.json.linq فئة
JToken المجردة لتمثيل البيانات ، والتي يتم من خلالها
توارث فئات JValue (لتمثيل القيم البسيطة)
وفئات JContainer (لتمثيل الهياكل). يمكن أن تكون الهياكل ، بدورها ،
JArray (صفيف) أو
JConstructor (مُنشئ) أو
JObject (كائن) أو
JProperty (خاصية).
تحتوي فئتا JArray و JObject على طريقة تحليل تسمح لك بتحويل بيانات JSON من سلسلة عادية إلى الكائنات المقابلة. لذلك ، إذا استخدمنا طريقة JObject.Parse (String) لبنية البيانات الخاصة بوظيفة Exmo trades:
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JObject jObject = JObject.Parse(responseBody);
سنرى بنية مكونة من عنصرين ، يمثل كل منهما زوجًا ذا قيمة رئيسية. سيكون المفتاح في هذه الحالة هو اسم زوج العملات (نوع السلسلة) ، وستكون القيمة قائمة المعاملات (نوع JToken):

الآن ، تتوفر قوائم المعاملات لنا مع مفاتيح "BTC_USD" و "USD_ETH". على سبيل المثال ، المعاملات على زوج العملات "BTC_USD":

ثم نحتاج فقط إلى ترجمة البيانات إلى نوع مناسب للعمل ، على سبيل المثال
قائمة <ترتيب> باستخدام الأسلوب ToObject <> ():
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JObject jObject = JObject.Parse(responseBody); JToken list = jObject["BTC_USD"]; List<Order> trades = list.ToObject<List<Order>>();
إما تحويل الهيكل كله لكتابة
قاموس <سلسلة ، قائمة <ترتيب>> :
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JObject jObject = JObject.Parse(responseBody); Dictionary<string, List<Order>> trades = new Dictionary<string, List<Order>>(); foreach (KeyValuePair<string, JToken> obj in jObject) trades.Add(obj.Key, obj.Value.ToObject<List<Order>>());
JSON Arrays (فئة JArray)
JSON Array هي مجموعة مرتبة من القيم. يبدأ الصفيف بعلامة '[' (قوس الفتحة المربعة) وينتهي بـ ']' (قوس المربع المغلق). القيم مفصولة بفاصلة.
يمكن رؤية شكل مجموعة JSON باتباع الرابط
https://api.exmo.com/v1/currency . إذا حاولت تحويله إلى JObject ، كما فعلنا مع الطلب السابق:
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/currency"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JObject jObject = JObject.Parse(responseBody);
سنحصل على استثناء Newtonsoft.Json.JsonReaderException يخبرنا أن البيانات التي يتم تحويلها ليست كائنًا.

يجب تحويل المصفوفات إلى نوع JArray خاص ، والذي ، مثل JObject ، يرث من JContainer.
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/currency"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JObject jObject = JObject.Parse(responseBody); JArray jArray = JArray.Parse(responseBody);
في حالة التحليل اللغوي ، فإن البنية الأولية غير معروفة مقدمًا ، أو تكون القدرة على معالجة كلا النوعين من البيانات مطلوبة - يمكنك تحديد JContainer أو JToken كنوع الكائن المحول ، ثم أثناء تحليل البيانات سيتم تحويلها ضمنيًا إلى النوع المطلوب.
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/currency"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JToken jArray = JToken.Parse(responseBody );
قيم JSON (فئة JValue)
وفقًا لوصف تنسيق JSON ، يمكن أن تكون القيمة عبارة عن سلسلة ذات علامات اقتباس مزدوجة أو رقم أو صواب أو خطأ أو لاغٍ أو
كائن أو
صفيف . هذه الهياكل يمكن أن تكون متداخلة. في تطبيق newotnsoft.json ، فقط الكائنات ذات الأنواع البسيطة يمكن أن تكون ذات قيمة. ستؤدي محاولة تحويل JArray إلى JValue إلى استثناء "System.InvalidCastException".
كمادة تمهيدية حول العمل بقيم محددة (فئة JValue) في مكتبة newtonsoft.json ، فإن الأمثلة من الوثائق
مرة ومرتين مناسبة تمامًا.
مثال للاستخدام للبيانات من التبادل:
HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/currency"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JArray jArray = JArray.Parse(responseBody ); foreach (JValue value in jArray) { string s = (string)value; }
في الجزء الثاني من المقالة ، سوف أصف بمزيد من التفصيل إمكانيات إعداد فصل لتحليل البيانات ، وكذلك بعض ميزات العمل مع نوع بيانات DateTime.
النص الكامل للبرنامج. using System.Threading.Tasks; using System.Collections.Generic; using System.Net.Http; using Newtonsoft.Json.Linq; namespace JSONObjects { class Order { public int trade_id { get; set; } public string type { get; set; } public double quantity { get; set; } public double price { get; set; } public double amount { get; set; } public int date { get; set; } } class Program { public static async Task Main(string[] args) { HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/currency"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JToken jArray = JToken.Parse(responseBody);
يمكن دائمًا العثور على المعلومات الأكثر اكتمالا وتفصيلا عن المكتبة في
الوثائق الرسمية .