###### 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);
```

上圖可以看到 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

```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

```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 %}