一般在處理 Json 內容時通常都是已經知道 Json 的格式,所以大部分都會先建立一個 class ,然後直接將 Json 內容反序列化為物件,簡單快速。
不過有些時候不會建立對應格式的類別,會想要直接動態的取得 Json 的某些屬性內容,那該怎麼做呢?
原始 Json 資料:
註:如果有多個內容屬性相同,則會回傳最後一個。
用起來也很簡單,只要把剛剛的 TryGetProperty 改為 TryGetPropertyIgnoreCase 即可
參考資料:
Microsoft.Learn - JsonDocument Class
Microsoft.Learn - JsonElement.TryGetProperty Method
動態取得 Json 內容
原始 Json:
[
{
"id": 1,
"name": "小明"
},
{
"id": 2,
"name": "大頭"
}
]
string json = "[{\"id\": 1, \"name\": \"小明\"}, {\"id\": 2, \"name\": \"大頭\"}]";
using JsonDocument document = JsonDocument.Parse(json);
JsonElement root = document.RootElement;
// 取得清單中的每一項
foreach (JsonElement jsonElement in root.EnumerateArray())
{
Console.WriteLine();
Console.WriteLine($"Value: {jsonElement}, Value Type: {jsonElement.ValueKind}");
// 取得物件中的所有屬性
foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
{
Console.WriteLine($"Name: {jsonProperty.Name}, Value: {jsonProperty.Value}, Value Type: {jsonProperty.Value.ValueKind}");
}
}
/*
Value: {"id": 1, "name": "小明"}, Value Type: Object
Name: id, Value: 1, Value Type: Number
Name: name, Value: 小明, Value Type: String
Value: {"id": 2, "name": "大頭"}, Value Type: Object
Name: id, Value: 2, Value Type: Number
Name: name, Value: 大頭, Value Type: String
*/
取得指定屬性內容
我們已經可以動態取得所有內容了,那我們先簡化一點,假設只有一個 Json Object,該如何動態取得指定的 Json 屬性內容呢?原始 Json 資料:
{
"id": 1,
"name": "小明"
}
string json = "{\"id\": 1, \"name\": \"小明\"}";
using JsonDocument document = JsonDocument.Parse(json);
JsonElement root = document.RootElement;
if (root.TryGetProperty("name", out JsonElement nameProperty))
{
string name = nameProperty.GetString() ?? string.Empty;
Console.WriteLine($"name: {name}");
}
else
{
Console.WriteLine("'name' property not found");
}
/*
name: 小明
*/
註:如果有多個內容屬性相同,則會回傳最後一個。
取得指定屬性內容且不區分大小寫
在上面的範例中 name 是小寫,如果使用 Name 或是 NAME 等只要大小寫不完全相同,就會取不到內容。 翻了一下文件,發現目前應該沒有內建的解決方式,筆者目前想到的是最笨的方法,就是一一比對屬性,然後比對時使用 StringComparison.OrdinalIgnoreCase 忽略大小寫。 為了方便複用,所以寫了一個擴充方法:
public static class JsonElementExtensions
{
public static bool TryGetPropertyIgnoreCase(this JsonElement element, string propertyName, out JsonElement value)
{
foreach (JsonProperty property in element.EnumerateObject())
{
if (property.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
{
value = property.Value;
return true;
}
}
value = default;
return false;
}
}
用起來也很簡單,只要把剛剛的 TryGetProperty 改為 TryGetPropertyIgnoreCase 即可
string json = "{\"id\": 1, \"name\": \"小明\"}";
using JsonDocument document = JsonDocument.Parse(json);
JsonElement root = document.RootElement;
// if (root.TryGetProperty("name", out JsonElement nameProperty))
if (root.TryGetPropertyIgnoreCase("Name", out JsonElement nameProperty))
{
string name = nameProperty.GetString() ?? string.Empty;
Console.WriteLine($"name: {name}");
}
else
{
Console.WriteLine("'name' property not found");
}
/*
name: 小明
*/
參考資料:
Microsoft.Learn - JsonDocument Class
Microsoft.Learn - JsonElement.TryGetProperty Method
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com