###### tags: `C#`,`2022` # System.Text.Json System.Text.Json是.NET Core 3.0新的命名空間,取代掉原本對Newtonsoft Json的依賴。 內建的System.Text.Json 效能更強大(利用Span<T>),也降低記憶體使用量,以下介紹一些常用的功能。 ## Serialize 序列化 物件解析成字串 參數之後可利用多載的方法,透過 JsonSerializerOptions 指定序列化的參數設定 ```csharp= string strJson = JsonSerializer.Serialize(object); ``` ## Deserialize 反序列化 字串解析成物件 ```csharp= var jsonString = @"{""PId"":1,""Name"":""Ashley""}"; var emp = JsonSerializer.Deserialize<Employee>(jsonString); ``` ## 屬性標示 如果希望有忽略或是變更名稱的屬性,可以加上以下標籤 ```csharp= public class Employee { [JsonIgnore] public int PId { get; set; } public string Name { get; set; } public Employee Manager { get; set; } [JsonPropertyName("DirectReports List")] public List<Employee> DirectReports { get; set; } } ``` ## 重複使用 JsonSerializerOptions 如果每次都new 一個新的實例,會導致效能下降 如果真的要改變JsonSerializerOptions,利用"複製"的方式來實作。 ```csharp= JsonSerializerOptions optionsCopy = new(options); ``` ![](https://i.imgur.com/evqIA0F.png) 上圖可以看到 options 的時間 和 每次都新增一個實力的時間,差非常多。 完整程式碼: ```csharp= Forecast forecast = new(DateTime.Now, 40, "Hot"); // WriteIndented: true 顯示容易閱讀的 JSON 格式 // 預設是 false 顯示最小化的JSON格式 JsonSerializerOptions options = new() { WriteIndented = true }; int iterations = 100000; var watch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { Serialize(forecast, options); } watch.Stop(); Console.WriteLine($"using one options instance: {watch.ElapsedMilliseconds}"); watch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { Serialize(forecast); } watch.Stop(); Console.WriteLine($"creating new options instances: {watch.ElapsedMilliseconds}"); JsonSerializerOptions optionsCopy = new(options); Console.WriteLine($"forecast Serialize : {JsonSerializer.Serialize(forecast, options)}"); // WriteIndented: true 顯示容易閱讀的 JSON 格式 // 預設是 false 顯示最小化的JSON格式 optionsCopy.WriteIndented = false; string forecastJson = JsonSerializer.Serialize<Forecast>(forecast, optionsCopy); Console.WriteLine($"optionsCopy Output JSON:\n{forecastJson}"); } private static void Serialize(Forecast forecast, JsonSerializerOptions? options = null) { _ = JsonSerializer.Serialize<Forecast>( forecast, options ?? new JsonSerializerOptions() { WriteIndented = true }); ``` ## JsonDocument Json讀取Sample ![](https://i.imgur.com/ctomzS7.png) ```csharp= var json = @"[ { ""PID"":1, ""Name"":""Ashley"" }, { ""PID"":2, ""Name"":""Alison"" } ]"; using (JsonDocument document = JsonDocument.Parse(json)) { var sumPid = 0; foreach (var element in document.RootElement.EnumerateArray()) { var tempCount = element.GetProperty("PID").GetInt16(); sumPid += tempCount; Console.WriteLine($"Name : {element.GetProperty("Name")}"); } Console.WriteLine($"sumPid : {sumPid}"); } ``` ## Utf8JsonWriter Json寫入Sample ![](https://i.imgur.com/4FueEeP.png) ```csharp= var options = new JsonWriterOptions { Indented = true }; using (var stream = new MemoryStream()) { using (var writer = new Utf8JsonWriter(stream, options)) { writer.WriteStartObject(); writer.WriteNumber("PID", 1); writer.WriteString("Name", "Ashley"); writer.WriteStartArray("ExtraNumberArray"); for (var i = 0; i < 5; i++) { writer.WriteNumberValue(i); } writer.WriteEndArray(); writer.WriteStartArray("ExtraArray"); writer.WriteStringValue("Ash"); writer.WriteStringValue(DateTime.Now); writer.WriteStringValue("425-000-1213"); writer.WriteNullValue(); writer.WriteEndArray(); writer.WriteStartObject("Address"); writer.WriteString("street", "street"); writer.WriteString("city", "Taipei"); writer.WriteNumber("zip", 110); writer.WriteString("option", string.Empty); writer.WriteStartArray("people"); writer.WriteStringValue("Ash"); writer.WriteStringValue("Ash2"); writer.WriteEndArray(); writer.WriteEndObject(); writer.WriteEndObject(); } string json = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(json); } ``` ## Reference [Microsoft Doc](https://docs.microsoft.com/zh-tw/dotnet/standard/serialization/system-text-json-configure-options?pivots=dotnet-6-0#reuse-jsonserializeroptions-instances) [黑暗執行緒](https://blog.darkthread.net/blog/system-text-json/) [遷移 Newtonsoft.Json 至 System.Text.Json](https://docs.microsoft.com/zh-tw/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to?pivots=dotnet-6-0) {%hackmd BJrTq20hE %}