# C#JSON匯入匯出(反序列化) 空白的JSON檔可以叫ChatGPT生成 也可以開一個空白的記事本,存檔的時候打.json [TOC] 將 JSON 反序列化 (JsonSerializer.Deserialize) 為 List< Table1 > 物件。 📌 JsonSerializer.Deserialize< T >() 將 JSON 字串轉換為 C# 物件 (List< Table1 >)。 假設 JsonString 是這樣的 JSON: ```csharp= [ { "name": "店家A", "about": "美食", "address": "台北", "traffic": "捷運", "time": "10:00-22:00" }, { "name": "店家B", "about": "咖啡廳", "address": "新北", "traffic": "公車", "time": "9:00-21:00" } ] ``` 反序列化後 (JsonData),會變成這樣的 C# 物件: ```csharp= JsonData = new List<Table1> { new Table1 { name = "店家A", about = "美食", address = "台北", traffic = "捷運", time = "10:00-22:00" }, new Table1 { name = "店家B", about = "咖啡廳", address = "新北", traffic = "公車", time = "9:00-21:00" } }; ``` ## 匯入 (內建) JsonSerializer為內建的 勾選:專案>加入參考>搜尋json>System.Text.Json、System.Memory勾選>確定 ```csharp= if(openFileDialog1.ShowDialog() == DialogResult.OK) { string json = File.ReadAllText(openFileDialog1.FileName); List<Table> importData = System.Text.Json.JsonSerializer.Deserialize<List<Table>>(json); if (importData != null) { record.Clear(); listBox1.Items.Clear(); foreach (var item in importData) { record[item.date] =$"-{item.who} {item.money} {item.pay}"; listBox1.Items.Add(item.date + $"-{item.who} {item.money} {item.pay}"); } MessageBox.Show("匯入成功"); } else { MessageBox.Show("匯入失敗,格式錯誤"); } } ``` ## 匯入 (工具方法) JsonConvert的方法 需在專案中加入Newtonsoft. Json套件,在工具->NuGet套件管理員->套件管理器主控台中輸入Install-Package Newtonsoft.Json ```csharp= using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; class Program { static void Main(string[] args) { string filePath = "data.json"; // 讀取 JSON 檔案 if (File.Exists(filePath)) { string json = File.ReadAllText(filePath); var users = JsonConvert.DeserializeObject<List<User>>(json);//反序列化 foreach (var user in users) { Console.WriteLine($"{user.Username} - {user.Password}"); } } else { Console.WriteLine("檔案不存在"); } } } ``` ## 將 List< T > 匯出為 JSON ```csharp= using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; class Program { static void Main(string[] args) { string filePath = "data.json"; var users = new List<User> { new User { Username = "newuser", Password = "password123" } }; // 轉換為 JSON 字串 string json = JsonConvert.SerializeObject(users, Formatting.Indented); // 儲存到檔案 File.WriteAllText(filePath, json); Console.WriteLine("資料已儲存為 JSON"); } } public class User { public string Username { get; set; } public string Password { get; set; } } ``` ## 將 DataTable 匯出為 JSON ```csharp= using System; using System.Data; using System.IO; using Newtonsoft.Json; class Program { static void Main() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("About", typeof(string)); dt.Columns.Add("Address", typeof(string)); dt.Columns.Add("Traffic", typeof(string)); dt.Columns.Add("Time", typeof(string)); dt.Rows.Add(1, "AAA", "Test", "Taipei", "MRT", "10:00"); dt.Rows.Add(2, "BBB", "Example", "Tainan", "Bus", "11:00"); string json = JsonConvert.SerializeObject(dt, Formatting.Indented);//轉 JSON File.WriteAllText("data.json", json);//儲存檔案 Console.WriteLine("JSON 檔案已儲存"); } } ``` ## 將 Database1Entities 的資料匯出 JSON ```csharp= using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; class Program { static void Main() { using (Database1Entities db = new Database1Entities()) // 連結資料庫 { var dataList = db.Table1.ToList(); // 查詢 Table1 內的所有資料 string json = JsonSerializer.Serialize(dataList, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText("database.json", json); // 儲存 JSON 檔案 Console.WriteLine("JSON 檔案已儲存"); } } } ``` ## Dictionary字典轉List< Table >匯出寫法 anna相關專案寫法 ```csharp= Dictionary<string, string> record = new Dictionary<string, string>(); if (openFileDialog1.ShowDialog() == DialogResult.OK) { 方法一: List<Table> list_table = record.Select(r => new Table { date = r.Key, who = r.Value.Split(' ')[0].Replace("-",""), money = r.Value.Split(' ')[1], pay = r.Value.Split(' ')[2] }).ToList(); //需在專案中加入Newtonsoft.Json套件,在工具->NuGet套件管理員->套件管理器主控台中輸入Install-Package Newtonsoft.Json string json = JsonConvert.SerializeObject(list_table, Newtonsoft.Json.Formatting.Indented); 方法二: var datatable = record.Select(r => new Table { date = r.Key, who = r.Value.Split(' ')[0].Replace("-", ""), money = r.Value.Split(' ')[1], pay = r.Value.Split(' ')[2] }).ToList(); // 新增到資料庫 db.Table.AddRange(datatable); db.SaveChanges(); // 儲存變更 string json = System.Text.Json.JsonSerializer.Serialize(datatable, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(openFileDialog1.FileName, json); MessageBox.Show("匯出成功"); } ``` ## 統整 ### JsonConvert的方法 ⚠️⚠️需在專案中加入Newtonsoft. Json套件,在工具->NuGet套件管理員->套件管理器主控台中輸入Install-Package Newtonsoft.Json下載 * 匯入 ```csharp= JsonConvert.DeserializeObject<List<User>>(json);//反序列化 ``` * 匯出 ```csharp= string json = JsonConvert.SerializeObject(list_table, Newtonsoft.Json.Formatting.Indented); ``` ### JsonSerializer 內建 ⚠️⚠️JsonSerializer為原本就在C#裡的,只需要勾選: 專案>加入參考>搜尋json>System.Text.Json、System.Memory勾選>確定 * 匯入 ```csharp= System.Text.Json.JsonSerializer.Deserialize<List<Table>>(json); ``` * 匯出 ```csharp= string json = System.Text.Json.JsonSerializer.Serialize(datatable, new JsonSerializerOptions { WriteIndented = true }); ``` ## 中文問題 JSON 預設會將非 ASCII 字符 (如中文) 轉成 Unicode (\uXXXX),但這不是亂碼,而是標準的 JSON 表示方式 如果想要讓 JSON 正常顯示中文,可以選擇 不使用 Unicode 轉義: ```csharp= "date": "2025\u5E742\u670826\u65E5" ``` ### 解決方法: * System.Text.Json ```csharp= var obj = new { date = "2025年2月26日" }; // 設定 JSON 不轉換 Unicode var options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // 讓 JSON 直接顯示中文 WriteIndented = true // 讓輸出格式更易讀 }; string json = JsonSerializer.Serialize(obj, options); Console.WriteLine(json); ``` * Newtonsoft.Json ```csharp= Formatting = Formatting.Indented, // 美化輸出(可選) StringEscapeHandling = StringEscapeHandling.Default // 讓中文顯示正常 ------------------------------------------------------------------- var obj = new { date = "2025年2月26日" }; string json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii // 取消 Unicode 轉換 }); Console.WriteLine(json); ``` 方法 | 適用場景 | 設定方式 -------------------|------------------------------|----------------------------------------------- System.Text.Json | .NET Core 3.0+ / .NET 5+ | Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping Newtonsoft.Json | .NET Framework / .NET Core / .NET 5+ | StringEscapeHandling = StringEscapeHandling.Default # 包含三個主要的資料表 1. customers(客戶) 1. services(服務) 1. appointments(預約) ## 定義 C# 類別 ```csharp= public class Customer { public int Id { get; set; } public string Name { get; set; } public string Phone { get; set; } public string Email { get; set; } } public class Service { public int Id { get; set; } public string ServiceName { get; set; } public int Duration { get; set; } public int Price { get; set; } } public class Appointment { public int Id { get; set; } public int CustomerId { get; set; } public int ServiceId { get; set; } public string AppointmentDate { get; set; } public string TimeSlot { get; set; } public string PaymentMethod { get; set; } } // 用來存整個 JSON 資料 public class Root { public List<Customer> customers { get; set; } public List<Service> services { get; set; } public List<Appointment> appointments { get; set; } } ``` ## 使用 JsonSerializer 讀取 JSON ```csharp= using System; using System.Collections.Generic; using System.IO; using System.Text.Json; class Program { static void Main() { // 讀取 JSON 檔案 string json = File.ReadAllText("data.json"); // 解析 JSON 成 Root 物件 Root data = JsonSerializer.Deserialize<Root>(json); // 測試輸出 Console.WriteLine("客戶名單:"); foreach (var customer in data.customers) { Console.WriteLine($"ID: {customer.Id}, 姓名: {customer.Name}, 電話: {customer.Phone}"); } Console.WriteLine("\n服務項目:"); foreach (var service in data.services) { Console.WriteLine($"ID: {service.Id}, 服務: {service.ServiceName}, 價格: {service.Price}"); } Console.WriteLine("\n預約記錄:"); foreach (var appointment in data.appointments) { Console.WriteLine($"預約ID: {appointment.Id}, 客戶ID: {appointment.CustomerId}, 服務ID: {appointment.ServiceId}, 日期: {appointment.AppointmentDate}"); } } } ``` ## 執行結果 **假設 data.json 內容如下:** ```json= { "customers": [ { "Id": 1, "Name": "王小明", "Phone": "0912345678", "Email": "ming@example.com" } ], "services": [ { "Id": 1, "ServiceName": "基本諮詢", "Duration": 30, "Price": 500 } ], "appointments": [ { "Id": 1, "CustomerId": 1, "ServiceId": 1, "AppointmentDate": "2025-03-25", "TimeSlot": "上午", "PaymentMethod": "現金" } ] } ``` 執行結果: ```markdown= 客戶名單: ID: 1, 姓名: 王小明, 電話: 0912345678 服務項目: ID: 1, 服務: 基本諮詢, 價格: 500 預約記錄: 預約ID: 1, 客戶ID: 1, 服務ID: 1, 日期: 2025-03-25 ``` ## 總結 1. 定義類別:對應 JSON 的 customers、services、appointments。 1. 使用 File.ReadAllText() 讀取 JSON,然後用 JsonSerializer.Deserialize< T >() 解析成 C# 物件。 1. 成功匯入 JSON,並可以操作 C# 物件! # Class裡包Class,DataGridView取值 (BatteryChargeRecord 包在 Vehicle 裡),我們可以用 C# 的 System.Text.Json 中的 JsonSerializer(內建於 .NET Core 和 .NET Framework 的新版本)來實作。 ## 1. 資料結構 Class 建立 ```csharp= public class Vehicle { public string ID { get; set; } public string BrandModel { get; set; } public string ModelName { get; set; } public List<BatteryChargeRecord> BatteryChargeRecord { get; set; } = new List<BatteryChargeRecord>(); } public class BatteryChargeRecord { public string ID { get; set; } public string ChargeStartDateTime { get; set; } public string ChargeEndDateTime { get; set; } public double ChargeStartCapacity { get; set; } public double ChargeEndCapacity { get; set; } public double ExpectedMaxCapacity { get; set; } } ``` ## 2. 匯出程式碼邏輯(從 DataGridView) ```csharp= using System.Text.Json; using System.Text.Json.Serialization; // 假設這是你提供的外層車輛資訊 var vehicle = new Vehicle { ID = "08566C56-9A72-45CA-AB2B-021A258D55B6", BrandModel = "215501", ModelName = "ZEVX", BatteryChargeRecord = new List<BatteryChargeRecord>() }; // 清除舊資料(重要:避免重複) vehicle.BatteryChargeRecord.Clear(); // 迭代 DataGridView 裡面的每一列 foreach (DataGridViewRow row in dataGridView1.Rows) { // 忽略空列(新增列) if (row.IsNewRow) continue; var record = new BatteryChargeRecord { ID = Guid.NewGuid().ToString(), ChargeStartDateTime = row.Cells["ChargeStartDateTime"].Value?.ToString(), ChargeEndDateTime = row.Cells["ChargeEndDateTime"].Value?.ToString(), ChargeStartCapacity = Convert.ToDouble(row.Cells["ChargeStartCapacity"].Value), ChargeEndCapacity = Convert.ToDouble(row.Cells["ChargeEndCapacity"].Value), ExpectedMaxCapacity = Convert.ToDouble(row.Cells["ExpectedMaxCapacity"].Value) }; vehicle.BatteryChargeRecord.Add(record); } ``` ## 3. 匯出成 JSON 檔案或字串 ```csharp= var options = new JsonSerializerOptions { WriteIndented = true // 格式化排版比較好看 }; string json = JsonSerializer.Serialize(vehicle, options); // 顯示或存檔都可以: Console.WriteLine(json); // File.WriteAllText("output.json", json); ``` ## 匯出a資料!! ```json= { "ID": "08566C56-9A72-45CA-AB2B-021A258D55B6", "BrandModel": "215501", "ModelName": "ZEVX", "BatteryChargeRecord": [ { "ID": "EFC91132-842F-41CC-A226-973D8B534D3D", "ChargeStartDateTime": "2022-05-02 07:48:09 +08:00", "ChargeEndDateTime": "2022-05-02 10:48:09 +08:00", "ChargeStartCapacity": 18.62, "ChargeEndCapacity": 33.90, "ExpectedMaxCapacity": 38.50 } ] } ```