首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 輕量級 JSON 序列化工具類 ConvertJson:零依賴支援 List、DataTable、DataReader 全轉換

     編輯:關於C語言

前言:為什麼要自製 JSON 工具?

Newtonsoft.Json / System.Text.Json 功能強大,但若專案僅需簡單的物件↔JSON 轉換,引入大型套件屬於「殺雞用牛刀」。本文提供一個 零第三方依賴、單一檔案、約 300 行 的 ConvertJson 靜態類,涵蓋 List、單一物件、DataSet、DataTable、DataReader 等常見資料源,適合輕量級專案或受限環境直接複製使用。

核心功能一覽

方法輸入輸出典型場景
ListToJson<T>(IList<T>)泛型集合JSON 字串實體清單序列化
ToJson(object)單一物件JSON 字串DTO 序列化
ToJson(IEnumerable)非泛型集合JSON 陣列舊版 ArrayList 等
ToJson(DataSet)DataSet巢狀 JSON多表資料集
ToJson(DataTable)DataTableJSON 陣列單表查詢結果
ToJson(DbDataReader)DataReaderJSON 陣列高效流式讀取

關鍵實作細節

1. 特殊字元義

private static string EscapeJson(string s)
{
    var sb = new StringBuilder();
    foreach (char c in s)
    {
        switch (c)
        {
            case '"': sb.Append("\\\""); break;
            case '\\': sb.Append("\\\\"); break;
            case '/': sb.Append("\\/"); break;
            case '\b': sb.Append("\\b"); break;
            case '\f': sb.Append("\\f"); break;
            case '\n': sb.Append("\\n"); break;
            case '\r': sb.Append("\\r"); break;
            case '\t': sb.Append("\\t"); break;
            default: sb.Append(c); break;
        }
    }
    return sb.ToString();
}

2. 型別感知格式化

private static string FormatValue(string raw, Type type)
{
    if (type == typeof(string))
        return $"\"{EscapeJson(raw)}\"";
    if (type == typeof(DateTime) || type == typeof(Guid) || type == typeof(TimeSpan))
        return $"\"{raw}\"";
    if (type == typeof(bool))
        return raw.ToLower();
    if (string.IsNullOrEmpty(raw) && type != typeof(string))
        return "\"\""; // 非字串型別的 null/空值輸出空字串
    return raw; // 數值型別直接輸出
}

3. 反射遍歷屬性(List/物件通用)

public static string ListToJson<T>(IList<T> list, string jsonName = null)
{
    if (list == null || list.Count == 0) return $"{{\"{(jsonName ?? typeof(T).Name)}\":[]}}";

    var sb = new StringBuilder();
    string rootName = jsonName ?? list[0].GetType().Name;
    sb.Append($"{{\"{rootName}\":[");

    var props = typeof(T).GetProperties();
    for (int i = 0; i < list.Count; i++)
    {
        sb.Append("{");
        for (int j = 0; j < props.Length; j++)
        {
            var val = props[j].GetValue(list[i]);
            string strVal = val?.ToString() ?? "";
            sb.Append($"\"{props[j].Name}\":{FormatValue(strVal, props[j].PropertyType)}");
            if (j < props.Length - 1) sb.Append(",");
        }
        sb.Append("}");
        if (i < list.Count - 1) sb.Append(",");
    }
    sb.Append("]}");
    return sb.ToString();
}

4. DataTable 高效轉換

public static string ToJson(DataTable dt, string jsonName = null)
{
    var sb = new StringBuilder();
    string name = jsonName ?? dt.TableName;
    sb.Append($"{{\"{name}\":[");

    foreach (DataRow row in dt.Rows)
    {
        sb.Append("{");
        for (int c = 0; c < dt.Columns.Count; c++)
        {
            var col = dt.Columns[c];
            string val = row[c]?.ToString() ?? "";
            sb.Append($"\"{col.ColumnName}\":{FormatValue(val, col.DataType)}");
            if (c < dt.Columns.Count - 1) sb.Append(",");
        }
        sb.Append("},");
    }
    if (dt.Rows.Count > 0) sb.Length--; // 移除最後逗號
    sb.Append("]}");
    return sb.ToString();
}

使用範例

// 1. List 序列化
var users = new List { new User { Id = 1, Name = "張三" } };
string json = ConvertJson.ListToJson(users);
// {"User":[{"Id":1,"Name":"張三"}]}

// 2. DataTable 序列化
DataTable dt = GetDataTableFromDb();
json = ConvertJson.ToJson(dt, "Users");

// 3. DataReader 串流轉換(不載入全表到記憶體)
using (var reader = cmd.ExecuteReader())
    json = ConvertJson.ToJson(reader);

已知限制與擴充建議

  • 不支援巢狀物件/集合屬性:目前僅處理純量屬性,若需巢狀序列化請自行擴充 FormatValue 遞迴處理 IEnumerable 與複雜型別。
  • DateTime 格式固定:輸出 .NET 預設 ToString() 格式,若需 ISO 8601 請在 FormatValue 加入 DateTime.Parse(val).ToString("o")。
  • 效能:反射 + StringBuilder 適合中小資料量(<10 萬筆),大量資料建議改用 System.Text.Json 的 Utf8JsonWriter 零配置寫入。
  • 反序列化:本類別僅提供「寫入」,若需「讀取」請搭配 System.Text.Json.JsonSerializer.Deserialize 或自行實作解析器。

完整原始碼下載

完整 ConvertJson.cs 已整理為單一檔案,可直接拖入專案使用。命名空間建議調整為專案專屬(如 MyProject.Utils),避免衝突。

總結

在無法引入 NuGet 套件、或追求極致輕量的情境下,ConvertJson 提供了「夠用、好改、零依賴」的 JSON 序列化能力,涵蓋 ADO.NET 主流資料容器,是工具箱裡的實用小刀。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved