文章目錄
[C#] 將 .NET Core 中的 Configuration 輸出為 JSON
之前筆記 [C#] 將 Dictionary 轉為 JSON 紀錄到 將 Dictionary 轉為 JSON 的方式,對 .NET Core 有些認識的朋友馬上就想到是為了處理 .NET Core Configuration,主要需求就是將搭配不同環境 build 完的最終版 Configuration 存回 JSON 之中,因為沒找到方法所以只好硬來,同事看完後覺得可以試試 Configuration.GetSection 遞迴方式來處理可能會簡單些,既然有方向就來試試囉
基本環境說明
- macOS Catalina 10.15.2
- .NET Core SDK 3.1.101
- C# 8.0
原始 JSON
{ "widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500 }, "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center" }, "text": { "data": "Click Here", "size": 36, "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" } } }
程式碼與實際效果
程式碼
private static JObject ToJson(IEnumerable<IConfigurationSection> configurationSections) { JContainer result = null; var setting = new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Merge}; var enumerable = configurationSections as IConfigurationSection[] ?? configurationSections.ToArray(); // 檢查是否是 array:value 不為 null 表示為最底層; array 的元素 key 會是 int (可能出現誤判);最後是 path 扣掉 int 的部份如果都是相同值就進一步確認為 array if (enumerable.All(a => a.Value != null && int.TryParse(a.Key, out var _)) && enumerable.Select(a => a.Path.Split(":").Reverse().Skip(1).First()).Distinct().Count() == 1) { var tmpList = new List<string>(); tmpList.AddRange(enumerable.Select(a => a.Value)); //取得 array 名稱 var key = enumerable.Select(a => a.Path.Split(":").Reverse().Skip(1).First()).First(); result = new JObject {{key, JToken.FromObject(tmpList)}}; return (JObject) result; } foreach (var child in enumerable) { var obj = new JObject(); if (string.IsNullOrWhiteSpace(child.Value)) { var toJson = ToJson(child.GetChildren()); // 如果是 array 的話,就換掉整個 object,避免多一層相同 property name if (toJson.ContainsKey(child.Key)) { obj = toJson; } else { obj.Add(child.Key, ToJson(child.GetChildren())); } } else { //處理轉型,這邊只寫了 int 與 bool if (int.TryParse(child.Value, out var intValue)) { obj.Add(child.Key, intValue); } else if (bool.TryParse(child.Value, out var boolValue)) { obj.Add(child.Key, boolValue); } else { obj.Add(child.Key, child.Value); } } if (result == null) { result = obj; } else { result.Merge(obj, setting); } } return (JObject) result; }
實際使用方式
將 ConfigurationBuilder build 完的 config 使用
GetChildren
之前傳入ToJson(configRoot.GetChildren()).ToString()
實際效果
原始 Dictionary
json string
心得
原本傻傻地要直接上手工轉換的版本,幸虧強大的同事提點才可以學到更適合的方式,有強大的同事真好,不過這也再次驗證了對於 .NET Core 我的掌握度還是很不足 XD
參考資訊
文章作者 Yowko Tsai
上次更新 2020-12-11
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。