کار با JSON در C # و VB
نویسنده :
این مقاله با الهام از بسیاری از سوالاتی که در بخش پرسش و پاسخ سریع پروژه این وب سایت ارائه شده است ، می باشد
کار با JSON در C # و VB
در این مقاله ، نحوه کار با انواع مقادیر استاندارد ، انواع مقدارهای سفارشی ، ساختارهای فشرده سازی به انواع دیگر و تبدیل از ساختار داده خام JSON به ساختارهای طبقه ای که نیازهای برنامه های ما را پشتیبانی می کنند ، خواهیم دید.
معرفی
در حالی که JSON یک فرم ذخیره سازی و تبادل داده متقابل و آسان برای خواندن است ، اما انعطاف پذیری ارائه شده برای تجزیه داده ها بعضی اوقات نیاز به برخی از تغییرات دارد.
این مقاله با الهام از بسیاری از سوالاتی که در بخش پرسش و پاسخ سریع پروژه این وب سایت ارائه شده است ، می باشد. ما از چندین مثال اساسی و پیشرفته در زندگی واقعی ، از Etsy ، Flickr ، MovieDB ، Google Drive و Twitter ، و راه حل هایی برای سفارش سازی اشیا simple ساده تا مبدل های سفارشی و تبدیل داده ها استفاده خواهیم کرد.
ابزارها و کتابخانه ها
مانند هر چیز ، شما به ابزار مناسب برای کار نیاز دارید. در اینجا برخی از ابزارهای موجود از جمله موارد استفاده شده در این مقاله وجود دارد.
گاهی اوقات ، داده های JSON بسته بندی می شوند و بسیار خوانا نیستند یا ما باید داده های خام را تأیید کنیم:
freeformatter.com - پشتیبانی جامع از چندین قالب
codebeautify.org - پشتیبانی جامع از چندین قالب
jsonformatter.org - زیباسازی ، اعتبارسنجی ، تبدیل JSON & XML
jsonformatter.curiousconcept.com - قالب و اعتبارسنجی JSON در برابر استاندارد RFC 4627 ، RFC 7159 ، ECMA-404
jsonlint.com - اعتبارسنجی JSON
Visual Studio (VS) Addin: JSON Viewer - قالب بندی ، چاپ ، مقایسه و اعتبارسنجی JSON
Fiddler - رفع اشکال در وب برای مشاهده ترافیک داده HTTP ؛ ببینید چه چیزی در واقع از طرف ارائه دهنده داده ارسال می شود
ما برای تبدیل داده های JSON خام به یک ساختار کلاس باید ایجاد کنیم. می توانید به صورت دستی کلاس هایی را از پرونده JSON ایجاد کنید که بسیار کند و زمان بر است. روش های بسیار سریعتری برای انجام این کار وجود دارد.
JSON Utils - از هر دو VB & C # با گزینه های زیادی پشتیبانی می کند
Visual Studio Addin: Json2Csharp - داده های JSON موجود در کلیپ بورد شما را به کلاس های C # تبدیل می کند
quicktype.io - از C # ، TypeScript ، Go Java ، Elm ، Swift ، Simple Types و Schemas پشتیبانی می کند.
برای پروژه های ساده ، هر 3 کتابخانه 100 99 99 of موارد مورد نیاز را پوشش می دهند. برای کارهای متوسط و پیشرفته تر مانند مبدل ها و تبدیل داده های سفارشی ، ما به کتابخانه Json.NET نیوتن سافت نیاز داریم. در ادامه این مقاله بیشتر توضیح میدهیم.
تبدیل داده
هنگامی که داده های JSON خام را در اختیار شما قرار گرفت و کلاس هایی را برای نقشه برداری از داده ها ایجاد کردید ، مرحله بعدی عیب یابی از کلاس ها و سفارشی سازی از کلاس ها است. این مقاله بر روی محرومیت زدایی تمرکز خواهد کرد. کلاس helper زیر این کار را ساده می کند.
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Support.CSharp
{
public static class JsonHelper
{
public static string FromClass(T data, bool isEmptyToNull = false,
JsonSerializerSettings jsonSettings = null)
{
string response = string.Empty;
if (!EqualityComparer.Default.Equals(data, default(T)))
response = JsonConvert.SerializeObject(data, jsonSettings);
return isEmptyToNull ? (response == "{}" ? "null" : response) : response;
}
public static T ToClass(string data, JsonSerializerSettings jsonSettings = null)
{
var response = default(T);
if (!string.IsNullOrEmpty(data))
response = jsonSettings == null
? JsonConvert.DeserializeObject(data)
: JsonConvert.DeserializeObject(data, jsonSettings);
return response;
}
}
}
VB :
Imports Newtonsoft.Json
Public Module JsonHelper
Public Function FromClass(Of T)(data As T,
Optional isEmptyToNull As Boolean = False,
Optional jsonSettings As JsonSerializerSettings = Nothing) _
As String
Dim response As String = String.Empty
If Not EqualityComparer(Of T).Default.Equals(data, Nothing) Then
response = JsonConvert.SerializeObject(data, jsonSettings)
End If
Return If(isEmptyToNull, (If(response = "{}", "null", response)), response)
End Function
Public Function ToClass(Of T)(data As String,
Optional jsonSettings As JsonSerializerSettings = Nothing) _
As T
Dim response = Nothing
If Not String.IsNullOrEmpty(data) Then
response = If(jsonSettings Is Nothing,
JsonConvert.DeserializeObject(Of T)(data),
JsonConvert.DeserializeObject(Of T)(data, jsonSettings))
End If
Return response
End Function
End Module
اجازه دهید ما با یک چیز ساده شروع کنیم. دو مثال زیر با داده های اولیه و مجموعه های .Net کار می کنند.
انواع ساده اشیا Simple
در اینجا یک شی Category از Etsy API وجود دارد. تمام زمینه های JSON به انواع داده های اولیه .NET ترسیم می شوند.
{
"category_id": 68890752,
"name": "gloves",
"meta_title": "Handmade Gloves on Etsy - Gloves, mittens, arm warmers",
"meta_keywords": "handmade gloves, gloves, handmade arm warmers,
handmade fingerless gloves, handmade mittens, hand knit mittens,
hand knit gloves, handmade accessories",
"meta_description": "Shop for unique, handmade gloves on Etsy,
a global handmade marketplace. Browse gloves, arm warmers,
fingerless gloves & more from independent artisans.",
"page_description": "Shop for unique, handmade gloves from our artisan community",
"page_title": "Handmade gloves",
"category_name": "accessories\/gloves",
"short_name": "Gloves",
"long_name": "Accessories > Gloves",
"num_children": 3
}
برای تهیه نقشه داده های JSON باید کلاس [هایی] ایجاد کنیم. برای این کار از JSON Utils استفاده خواهیم کرد:
در اینجا قرارداد نامگذاری پرونده Pascal را انتخاب کرده ایم. قسمتهای JSON همه با حروف کوچک هستند. با استفاده از ویژگی Json.NET JsonProperty ، نگاشت فیلدهای JSON به خصوصیات کلاس .NET کاملاً ساده است. در اینجا کلاس ایجاد شده است:
using Newtonsoft.Json;
namespace WinFormSimpleObject.Models
{
public class Category
{
[JsonProperty("category_id")]
public int CategoryId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("meta_title")]
public string MetaTitle { get; set; }
[JsonProperty("meta_keywords")]
public string MetaKeywords { get; set; }
[JsonProperty("meta_description")]
public string MetaDescription { get; set; }
[JsonProperty("page_description")]
public string PageDescription { get; set; }
[JsonProperty("page_title")]
public string PageTitle { get; set; }
[JsonProperty("category_name")]
public string CategoryName { get; set; }
[JsonProperty("short_name")]
public string ShortName { get; set; }
[JsonProperty("long_name")]
public string LongName { get; set; }
[JsonProperty("num_children")]
public int NumChildren { get; set; }
}
}
VB :
Imports Newtonsoft.Json
Namespace Models
Public Class Category
Public Property CategoryId As Integer
Public Property Name As String
Public Property MetaTitle As String
Public Property MetaKeywords As String
Public Property MetaDescription As String
Public Property PageDescription As String
Public Property PageTitle As String
Public Property CategoryName As String
Public Property ShortName As String
Public Property LongName As String
Public Property NumChildren As Integer
End Class
End Namespace
اکنون می توانیم داده های JSON را به کلاس [NET].
public Category Result { get; set; }
private const string fileName = "Etsy_Category.Json";
private readonly string filePath = Environment.CurrentDirectory;
private void GetData()
{
// Retrieve JSON data from file
var rawJson = File.ReadAllText(Path.Combine(filePath, fileName));
// Convert to C# Class typed object
Result = JsonHelper.ToClass(rawJson);
}
VB :
Public Property Result() As Category
Private Const fileName As String = "Etsy_Category.Json"
Private ReadOnly filePath As String = Environment.CurrentDirectory
Private Sub GetData()
' Retrieve JSON data from file
Dim rawJson = File.ReadAllText(Path.Combine(filePath, fileName))
' Convert to C# Class typed object
Result = JsonHelper.ToClass(Of Category)(rawJson)
End Sub
و اکنون می توانید با داده ها کار کنید.
انواع ساده مجموعه
Etsy API ، مانند بسیاری از API های دیگر ، نه تنها با اشیا single منفرد بلکه با مجموعه اشیا wra پیچیده شده در یک پاسخ JSON کار می کند.
{
"count": 27,
"results": [{
"category_id": 68890752,
"name": "gloves",
"meta_title": "Handmade Gloves on Etsy - Gloves, mittens, arm warmers",
"meta_keywords": "handmade gloves, gloves, handmade arm warmers,
handmade fingerless gloves, handmade mittens, hand knit mittens,
hand knit gloves, handmade accessories",
"meta_description": "Shop for unique, handmade gloves on Etsy,
a global handmade marketplace. Browse gloves, arm warmers,
fingerless gloves & more from independent artisans.",
"page_description": "Shop for unique, handmade gloves from our artisan community",
"page_title": "Handmade gloves",
"category_name": "accessories\/gloves",
"short_name": "Gloves",
"long_name": "Accessories > Gloves",
"num_children": 3
},
{
"category_id": 68890784,
"name": "mittens",
"meta_title": "Handmade Mittens on Etsy - Mittens, gloves, arm warmers",
"meta_keywords": "handmade mittens, handcrafted mittens, mittens,
accessories, gloves, arm warmers, fingerless gloves, mittens,
etsy, buy handmade, shopping",
"meta_description": "Shop for unique, handmade mittens on Etsy,
a global handmade marketplace. Browse mittens, arm warmers,
fingerless gloves & more from independent artisans.",
"page_description": "Shop for unique, handmade mittens from our artisan community",
"page_title": "Handmade mittens",
"category_name": "accessories\/mittens",
"short_name": "Mittens",
"long_name": "Accessories > Mittens",
"num_children": 4
}],
"params": {
"tag": "accessories"
},
"type": "Category",
"pagination": {
}
}
c#:
public class Pagination
{
[JsonProperty("effective_limit")]
public int? EffectiveLimit { get; set; }
[JsonProperty("effective_offset")]
public int? EffectiveOffset { get; set; }
[JsonProperty("effective_page")]
public int? EffectivePage { get; set; }
[JsonProperty("next_offset")]
public int? NextOffset { get; set; }
[JsonProperty("next_page")]
public int? NextPage { get; set; }
}
public class Params
{
[JsonProperty("tag")]
public string Tag { get; set; }
}
public class Response where TModel : class
{
[JsonProperty("count")]
public int Count { get; set; }
[JsonProperty("results")]
public IList Results { get; set; }
[JsonProperty("params")]
public Params Params { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("pagination")]
public Pagination Pagination { get; set; }
}
VB :
Public Class Pagination
Public Property EffectiveLimit() As Integer?
Public Property EffectiveOffset() As Integer?
Public Property EffectivePage() As Integer?
Public Property NextOffset() As Integer?
Public Property NextPage() As Integer?
End Class
Public Class Params
Public Property Tag As String
End Class
Public Class Response(Of TModel As Class)
Public Property Count As Integer
Public Property Results As IList(Of TModel)
Public Property Params As Params
Public Property Type As String
Public Property Pagination As Pagination
End Class
اکنون می توانیم داده های JSON را به کلاس .Net [es] تبدیل کنیم:
public BindingList Categories { get; set; }
private void GetData()
{
// Retrieve JSON data from file
var rawJson = File.ReadAllText(Path.Combine(filePath, fileName));
// Convert to C# Class typed object
var response = JsonHelper.ToClass>(rawJson);
// Get collection of objects
if (response != null && response.Results != null && response.Results.Count > 0)
{
var data = response.Results;
Categories.Clear();
for (int i = 0; i < data.Count; i++)
{
Categories.Add(data[i]);
}
}
}
VB :
Public Property Categories() As BindingList(Of Category)
Private Sub GetData()
' Retrieve JSON data from file
Dim rawJson = File.ReadAllText(Path.Combine(filePath, fileName))
' Convert to C# Class typed object
Dim response = JsonHelper.ToClass(Of Response(Of Category))(rawJson)
' Get collection of objects
If response IsNot Nothing _
AndAlso response.Results IsNot Nothing _
AndAlso response.Results.Count > 0 Then
Dim data = response.Results
Categories.Clear()
For i As Integer = 0 To data.Count - 1
Categories.Add(data(i))
Next
End If
End Sub
انواع غیراستاندارد و انواع ساختار داده ها
همه زبان ها در همه سیستم عامل ها انواع داده سازگار ندارند.
مهر زمانهای UNIX Epoch
مهر زمان یونیکس چیست؟ با توجه به Wikipedia.org:
نقل قول:
سیستمی برای توصیف لحظه به لحظه ، تعریف شده به تعداد ثانیه های سپری شده از ساعت 00:00:00 ساعت جهانی هماهنگ (UTC) ، پنجشنبه ، 1 ژانویه 1970 ، [1] [یادداشت 1] منهای تعداد ثانیه های جهشی که از آن زمان اتفاق افتاده است
در اینجا مثالی از توییتر آورده شده است:
"reset": 1502612374
و در اینجا مثالی از Flickr آورده شده است:
"lastupdate": "1502528455"
ما می توانیم یک قسمت خاصیت عدد صحیح داشته باشیم و مهر تایم دوره عدد صحیح را به یک نوع DateTime پس از رفع عیب تبدیل کنیم. راه حل جایگزین و بهتر استفاده از ویژگی JsonConverter است:
internal static class Unix
{
internal static readonly DateTime Epoch = new DateTime
(year: 1970, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0,
kind: DateTimeKind.Utc);
}
public static class DoubleExtensions
{
public static DateTime FromUnixDate(this double? unixDate)
{
return Unix.Epoch.AddSeconds(unixDate ?? 0.0);
}
public static DateTime FromUnixDate(this double unixDate)
{
return Unix.Epoch.AddSeconds(unixDate);
}
}
public sealed class JsonUnixDateConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
double value = 0;
if (double.TryParse(Convert.ToString(reader.Value), out value))
return value.FromUnixDate();
if (objectType == typeof(DateTime))
return default(DateTime);
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
VB :
Friend Module Unix
Friend ReadOnly Epoch As New DateTime(year:=1970, month:=1, day:=1,
hour:=0, minute:=0, second:=0, millisecond:=0, kind:=DateTimeKind.Utc)
End Module
Public Module DoubleExtensions
Public Function FromUnixDate(unixDate As Double?) As DateTime
Return Epoch.AddSeconds(If(unixDate, 0.0))
End Function
Public Function FromUnixDate(unixDate As Double) As DateTime
Return Epoch.AddSeconds(unixDate)
End Function
End Module
Public NotInheritable Class JsonUnixDateConverter : Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType Is GetType(DateTime) OrElse objectType Is GetType(Date?)
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type,
existingValue As Object, serializer As JsonSerializer) As Object
Dim value As Double = 0
If Double.TryParse(Convert.ToString(reader.Value), value) Then
Return value.FromUnixDate()
End If
If objectType Is GetType(DateTime) Then
Return Nothing
End If
Return Nothing
End Function
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object,
serializer As JsonSerializer)
Throw New NotImplementedException()
End Sub
End Class
چگونه کار می کند
JsonUnixDateConverter.CanConvert می تواند نوع یا داده های صحیح را بررسی کند. در صورت تطابق ، JsonUnixDateConverter.ReadJson اجرا ، تجزیه مقدار ، تبدیل از دوره یونیکس به .Net Date نوع ، و مقدار را به خصوصیت کلاس اختصاص داده است.
نحوه استفاده
نگران نباشید ، JsonUnixDateConverter را روی ویژگی اعمال کنید:
[JsonProperty("lastupdate"), JsonConverter(typeof(JsonUnixDateConverter))]
public DateTime? LastUpdate { get; set; }
VB :
Public Property LastUpdate() As Date?
انواع ساختار داده ها
برخی از ارائه دهندگان داده از چندین قالب داده پشتیبانی می کنند: XML ، JSON و غیره ... و تفاوت در قالب می تواند انواع جالب توجهی در داده ها ایجاد کند. انواع ساختار داده ها جایی است که یک نوع متغیر منفرد به جای یک مقدار ساده به عنوان یک شی توصیف می شود.
مثالی از این مورد ، شی Photo Photo و قسمت شمارش نظرات است:
{
"photo": {
"comments": {
"_content": "483"
}
}
}
اگر ما ترجمه یک به یک را انجام دهیم ، کلاس های مورد نیاز عبارتند از:
public class Comments
{
[JsonProperty("_content")]
public int Count { get; set; }
}
public class Photo
{
[JsonProperty("comments")]
public Comments Comments { get; set; }
}
سپس برای استفاده از ساختار کلاس فوق:
int GetCommentCount(Photo photo)
{
return photo.Comments.Count;
}
خیلی بهتر خواهد بود اگر بتوانیم تعداد نظرات را به جای یک شی کلاس ، به یک عدد صحیح ساده کنیم:
int GetCommentCount(Photo photo)
{
return photo.CommentCount;
}
ادامه در مقالات بعدی ما ... به زودی ...