Chuyển đến nội dung chính

Kết hợp Newtonsoft.Json và System.Text.Json để xử lý đối tượng với chức năng serialization và Deserialization


Giới thiệu

Các dữ liệu JSON thường được sử dụng trong ứng dụng web, đặc biệt là Web API, Serverless. Chính vì vậy từ .NET Core 3.0, Microsoft đã đưa System.Text.Json vào Framework và ngày càng xử lý tốt hơn.
Trong bài viết này, mình sẽ tìm hiểu cách sử dụng cơ bản của 2 thư viện trên, và cách xử lý lỗi khi serialize object trên Azure Functions.

JSON là gì?

JSON là viết tắt của JavaScript Object Notation, là một kiểu định dạng dữ liệu tuân theo một quy luật nhất định mà hầu hết các ngôn ngữ lập trình hiện nay đều có thể đọc được. JSON là một tiêu chuẩn mở để trao đổi dữ liệu trên web.

JavaScript Object Notation - JSON

Serialize và deserializie là gì?

Trong C#, serialization là quá trình chuyển đổi đối tượng sang byte stream để có thể lưu vào memory, file hoặc database. Quá trình ngược lại gọi là deserialization

Serialize an object
Deserialzie byte stream to object

Ví dụ sử dụng serialization và deserialization

Tạo 2 class Person và Pet
class Person
{
	public string Name { get; set; }
	public int Age { get; set; }
	public string StateOfOrigin { get; set; }
	public List<Pet> Pets { get; set; }
}
class Pet
{
	public string Type { get; set; }
	public string Name { get; set; }
	public double Age { get; set; }
}
Bạn tạo data như sau:
var jsonPerson = @"{""Name"":""John"",
                        ""Age"":34,
                        ""StateOfOrigin"":""England"",
                        ""Pets"":
                            [{""Type"":""Cat"",""Name"":""MooMoo"",""Age"":3.4},
                            {""Type"":""Squirrel"",""Name"":""Sandy"",""Age"":7}]}";

Deserialize

Newtonsoft.Json
Đầu tiên, bạn cần cài đặt package Newtonsoft.Json từ nuget package. Thực hiện việc chuyển từ chuỗi Json sang .NET Object: 


using Newtonsoft.Json;
//---
DeserizalizeExampleWithJsonNet(jsonPerson);
//--
static Person DeserizalizeExampleWithJsonNet(string jsonPerson)
{
    var personObject = JsonConvert.DeserializeObject<Person>(jsonPerson);
    Console.WriteLine($"Person's name: {personObject.Name}");
    Console.WriteLine($"Person's age: {personObject.Age}");
    Console.WriteLine($"Person's first pet's name: {personObject.Pets.First().Name}");
    return personObject;
}
System.Text.Json
Class JsonSerializer: serialize và deserialize JSON bằng các phương thức như Serialize(), Deserialize(), SerializeAsync(), v.v.
using System.Text.Json;
//---
DeserizalizeExample(jsonPerson);
//--
static Person DeserizalizeExample(string jsonPerson)
{
    var personObject = JsonSerializer.Deserialize<Person>(jsonPerson);
    Console.WriteLine($"Person's name: {personObject.Name}");
    Console.WriteLine($"Person's age: {personObject.Age}");
    Console.WriteLine($"Person's first pet's name: {personObject.Pets.First().Name}");
    return personObject;
}

Serialize

System.Text.Json
static void SerializeExample()
{
    var pets = new List<Pet>
    {
        new Pet { Type = "Cat", Name = "MooMoo", Age = 3.4 },
        new Pet { Type = "Squirrel", Name = "Sandy", Age = 7 }
    };
    var person = new Person
    {
        Name = "John",
        Age = 34,
        StateOfOrigin = "England",
        Pets = pets
    };
    Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(person));
    Console.WriteLine(System.Text.Json.JsonSerializer.Serialize<Person>(person));
}
Newtonsoft.Json
static void SerializeExampleWithNewtonSoft()
{
    var pets = new List<Pet>
    {
        new Pet { Type = "Cat", Name = "MooMoo", Age = 3.4 },
        new Pet { Type = "Squirrel", Name = "Sandy", Age = 7 }
    };
    var person = new Person
    {
        Name = "John",
        Age = 34,
        StateOfOrigin = "England",
        Pets = pets
    };
    Console.WriteLine(JsonConvert.SerializeObject(person));
}

Kết hợp NewtonSoft với System.Text.Json

Sử dụng NewtonSoft

Convert json string sang kiểu Dynamic

"dynamic" với ý nghĩa như 1 con trỏ trong C/C++ và khi sử dụng, bạn có thể trỏ tới bất kỳ thuộc tính hoặc phương thức nào. Trình biên dịch không hề báo lỗi nhưng nếu có lỗi, nó sẽ phát sinh trong quá trình runtime.
public static (string? genre, double imdb, double rotten) UsingDynamic(string jsonString)
{
	var dynamicObject = JsonConvert.DeserializeObject<dynamic>(jsonString)!;
	var genre = dynamicObject.Genre;
	var imdb = dynamicObject.Rating.Imdb;
	var rotten = dynamicObject.Rating["Rotten Tomatoes"];
	return (genre, imdb, rotten);
}
Kết quả
Thriller
8.1
0.94

Sử dụng Expando Object

Cùng đoạn code trên, chúng ta sử dụng ExpandoObject thay vì dynamic
public static (string? genre, double imdb, double rotten) UsingExpandoObject(string jsonString)
{
	dynamic dynamicObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString)!;
	var genre = dynamicObject.Genre;
	var imdb = dynamicObject.Rating.Imdb;
	IDictionary<string, object> rating = dynamicObject.Rating;
	var rotten = (double)rating["Rotten Tomatoes"];
	return (genre, imdb, rotten);
}

Thực chất ExpandoObject kế thừa từ các lớp: IDynamicMetaObjectProvider, IDictionary, ICollection và IEnumerable,... Thay vì trình biên dịch sẽ báo lỗi trong quá trình runtime, nhưng do kế thừa từ interface đặc biệt là IDynamicMetaObjectProvider, nên nó sẽ tự động tạo ra các thuộc tính tương ứng cho từng loại dữ liệu.

Note: Bạn không thể áp dụng kiểu dynamic cho System.Text.Json

Convert json string sang kiểu Anonymous Object

public static (string? Genre, double Imdb) UsingAnonymousType(string jsonString)
{
	var anonymous = JsonConvert.DeserializeAnonymousType(jsonString, new
	{
		Genre = string.Empty,
		Rating = new { Imdb = 0d }
	})!;
	var genre = anonymous.Genre;
	var imdb = anonymous.Rating.Imdb;
	return (genre, imdb);
}

System.Text.Json

Sử dung JsonElement

// Native/GenreRatingFinder.cs
public static (string? Genre, double Imdb, double Rotten) UsingJsonElement(string jsonString)
{
    var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonString);
    return FromJsonElement(jsonElement);
}
private static (string? Genre, double Imdb, double Rotten) FromJsonElement(JsonElement jsonElement)
{
    var genre = jsonElement
        .GetProperty("Genre")
        .GetString();
    var imdb = jsonElement
        .GetProperty("Rating")
        .GetProperty("Imdb")
        .GetDouble();
    var rotten = jsonElement
        .GetProperty("Rating")
        .GetProperty("Rotten Tomatoes")
        .GetDouble();
    return (genre, imdb, rotten);
}

Tham khảo

Hiểu rõ về JSON là gì? Cách lấy dữ liệu từ JSON

Nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.