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

ASP.NET 將 DataReader 轉換為 JSON 字串工具類

     編輯:關於ASP.NET

在 Web Forms 時代,常需將 SqlDataReader 直接序列化為 JSON 供前端下拉選單、AJAX 回傳使用。雖然現代專案建議用 Entity Framework + JSON.NET (Newtonsoft.Json) / System.Text.Json,但維舊專案仍需此工具。以下提供健壯、可復用的實作。

工具類實作 (支援巢狀結構、日期格式化、Null 處理)


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using Newtonsoft.Json; // 建議引用 JSON.NET,內建序列化更可靠

public static class JsonHelper
{
    /// 
    /// 將 SqlDataReader 序列化為 JSON 字串 (使用 JSON.NET)
    /// 
    public static string ToJson(SqlDataReader reader, string rootName = "data")
    {
        if (reader == null) throw new ArgumentNullException(nameof(reader));
        
        var list = new List>();
        while (reader.Read())
        {
            var dict = new Dictionary(reader.FieldCount);
            for (int i = 0; i < reader.FieldCount; i++)
            {
                object val = reader.GetValue(i);
                // DBNull 轉 null,DateTime 格式化
                dict[reader.GetName(i)] = val == DBNull.Value ? null : 
                    (val is DateTime dt ? dt.ToString("yyyy-MM-dd HH:mm:ss") : val);
            }
            list.Add(dict);
        }
        
        var result = new Dictionary { [rootName] = list };
        return JsonConvert.SerializeObject(result, Formatting.None);
    }

    /// 
    /// 無 JSON.NET 依賴的手工實作 (舊專案相容)
    /// 
    public static string ToJsonManual(SqlDataReader reader, string tableName = "Table")
    {
        if (reader == null) throw new ArgumentNullException(nameof(reader));
        
        var sb = new StringBuilder();
        sb.Append('{').Append('"').Append(tableName).Append("\":{");
        sb.Append("\"records\":[");
        
        bool firstRow = true;
        try
        {
            while (reader.Read())
            {
                if (!firstRow) sb.Append(',');
                firstRow = false;
                
                sb.Append('{');
                bool firstCol = true;
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    if (!firstCol) sb.Append(',');
                    firstCol = false;
                    
                    string name = reader.GetName(i);
                    object val = reader.GetValue(i);
                    string jsonVal = val == DBNull.Value ? "null" : 
                        (val is string || val is DateTime || val is Guid ? 
                            "\"" + EscapeJson(val.ToString()) + "\"" : 
                            val.ToString().ToLower()); // bool/int/decimal 直接輸出
                    
                    sb.Append('"').Append(EscapeJson(name)).Append("\":").Append(jsonVal);
                }
                sb.Append('}');
            }
        }
        finally
        {
            reader.Close(); // 確保關閉 Reader
        }
        
        sb.Append("]}");
        return sb.ToString();
    }

    private static string EscapeJson(string s)
    {
        return s.Replace("\\", "\\\\")
                .Replace("\"", "\\\"")
                .Replace("\n", "\\n")
                .Replace("\r", "\\r")
                .Replace("\t", "\\t");
    }
}

使用範例


// Web Forms / ASMX / Generic Handler
public void GetProductsJson()
{
    string sql = "SELECT ProductID, ProductName, UnitPrice, Discontinued FROM Products";
    using (var conn = new SqlConnection(ConnStr))
    using (var cmd = new SqlCommand(sql, conn))
    {
        conn.Open();
        using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            string json = JsonHelper.ToJson(reader, "products");
            Response.ContentType = "application/json; charset=utf-8";
            Response.Write(json);
        }
    }
}

// 前端 jQuery 使用
$.getJSON('GetProductsJson.ashx', function(data) {
    $.each(data.products, function(i, item) {
        $('#ddlProduct').append($('

進階:直接序列化 DataTable / List<T> (現代做法)


// 使用 JSON.NET (專案建議安裝 Newtonsoft.Json NuGet)
public string GetProductsJsonModern()
{
    var dt = new DataTable();
    using (var da = new SqlDataAdapter("SELECT * FROM Products", ConnStr))
        da.Fill(dt);
    
    // DataTable 直接序列化
    string json = JsonConvert.SerializeObject(dt, Formatting.None);
    // 或轉為 List 更精確控制
    return json;
}

// 使用 System.Text.Json (.NET Core 3.0+ / .NET 5+)
using System.Text.Json;
public string GetProductsJsonCore()
{
    var list = new List();
    // ...填充資料...
    return JsonSerializer.Serialize(new { products = list }, new JsonSerializerOptions 
    { 
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    });
}


效能與記憶體考量

方法記憶體速度適用場景
DataReader + 手工 StringBuilder低 (串流)快大量資料、無 JSON.NET 環境
DataReader + JSON.NET中快一般專案、需日期/Null 處理
DataTable.Fill + 序列化高 (全載入記憶體)中小量資料、需 DataTable 功能
Entity Framework + 投影中中現代專案、強型別、LINQ 查詢

關鍵提醒

  • 務必關閉 Reader:using 或 finally { reader.Close(); },否則連線池洩漏。
  • 日期格式:統一 ISO 8601 (yyyy-MM-ddTHH:mm:ss) 或 Unix Timestamp,前端解析最穩定。
  • 編碼:Response.ContentType = "application/json; charset=utf-8",避免中文亂碼。
  • 安全性:公開 API 需加上驗證、速率限制、CORS 設定。

新專案請直接使用 System.Text.Json 或 Newtonsoft.Json 配合強型別模型,手工拼 JSON 僅限極舊環境維護。

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