---
# System prepended metadata

title: C#JSON匯入匯出(反序列化)
tags: [C#]

---

# 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
    }
  ]
}
```




