Converting DataTable to JSON in C#: Implementation Methods and Best Practices

Nov 16, 2025 · Programming · 12 views · 7.8

Keywords: C# | DataTable | JSON Conversion | JavaScriptSerializer | Json.NET

Abstract: This article provides a comprehensive exploration of three primary methods for converting DataTable to JSON objects in C#: manual construction using StringBuilder, serialization with JavaScriptSerializer, and efficient conversion via the Json.NET library. The analysis focuses on implementation principles, code examples, and applicable scenarios, with particular emphasis on generating JSON array structures containing outer 'records' keys. Through comparative analysis of performance, maintainability, and functional completeness, the article offers developers complete technical references and practical guidance.

Introduction

In modern web development, data serialization forms the core of frontend-backend interaction. JSON (JavaScript Object Notation), as a lightweight data interchange format, has gained widespread popularity due to its simplicity and cross-language compatibility. In C# development, there is frequent need to convert DataTable data obtained from database queries into JSON format for processing and display in JavaScript.

Basic Concepts of DataTable and JSON

DataTable is a crucial component in .NET Framework for in-memory data storage, typically used to store result sets obtained from database queries. JSON is a text-based data format that organizes data using key-value pairs, offering excellent readability and easy parsing capabilities.

Core Conversion Method Analysis

Method One: Using JavaScriptSerializer

System.Web.Script.Serialization.JavaScriptSerializer is .NET Framework's built-in JSON serialization tool, providing simple and easy-to-use APIs. Below is the core code for implementing DataTable to JSON conversion:

public string ConvertDataTableToJsonWithRecords(DataTable dt, string keyColumn)
{
    System.Web.Script.Serialization.JavaScriptSerializer serializer = 
        new System.Web.Script.Serialization.JavaScriptSerializer();
    
    List<Dictionary<string, object>> records = new List<Dictionary<string, object>>();
    
    foreach (DataRow row in dt.Rows)
    {
        Dictionary<string, object> record = new Dictionary<string, object>();
        
        // Add primary key field
        record.Add(keyColumn, row[keyColumn]);
        
        // Add other fields
        foreach (DataColumn column in dt.Columns)
        {
            if (column.ColumnName != keyColumn)
            {
                record.Add(column.ColumnName, row[column]);
            }
        }
        
        records.Add(record);
    }
    
    // Build final JSON object containing records key
    Dictionary<string, object> result = new Dictionary<string, object>
    {
        { "records", records }
    };
    
    return serializer.Serialize(result);
}

The core concept of this method involves converting each row of the DataTable into a Dictionary object, where keys are column names and values are corresponding data. These Dictionary objects are then collected into a List, finally wrapped in an outer object containing the "records" key for serialization.

Method Two: Using Json.NET Library

Json.NET (Newtonsoft.Json) is currently the most popular JSON serialization library, offering richer functionality and better performance. Here is the implementation using Json.NET:

public string ConvertDataTableToJsonWithJsonNet(DataTable dt, string keyColumn)
{
    var records = new List<Dictionary<string, object>>();
    
    foreach (DataRow row in dt.Rows)
    {
        var record = new Dictionary<string, object>();
        
        // Explicitly handle each field to ensure correct data types
        foreach (DataColumn column in dt.Columns)
        {
            object value = row[column];
            
            // Handle DBNull values
            if (value == DBNull.Value)
            {
                value = null;
            }
            
            record[column.ColumnName] = value;
        }
        
        records.Add(record);
    }
    
    var result = new { records = records };
    return JsonConvert.SerializeObject(result, Formatting.Indented);
}

Method Three: Manual Construction Using StringBuilder

Although this method involves more verbose code, it still holds value in specific scenarios (such as when highly customized JSON structures are needed or when avoiding external dependencies):

public string ConvertDataTableToJsonManual(DataTable dt)
{
    if (dt.Rows.Count == 0)
        return "{\"records\":[]}";
    
    StringBuilder jsonBuilder = new StringBuilder();
    jsonBuilder.Append("{\"records\":[");
    
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        jsonBuilder.Append("{");
        
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            string columnName = dt.Columns[j].ColumnName;
            object value = dt.Rows[i][j];
            
            jsonBuilder.Append($"\"{columnName}\":");
            
            // Format appropriately based on data type
            if (value == DBNull.Value)
            {
                jsonBuilder.Append("null");
            }
            else if (value is string || value is DateTime)
            {
                jsonBuilder.Append($"\"{value.ToString().Replace(\"\"\", \"\\\"\")}\"");
            }
            else
            {
                jsonBuilder.Append(value.ToString());
            }
            
            if (j < dt.Columns.Count - 1)
                jsonBuilder.Append(",");
        }
        
        jsonBuilder.Append("}");
        if (i < dt.Rows.Count - 1)
            jsonBuilder.Append(",");
    }
    
    jsonBuilder.Append("]}");
    return jsonBuilder.ToString();
}

Method Comparison and Selection Recommendations

Performance Comparison

Json.NET typically outperforms JavaScriptSerializer in serialization performance, especially when handling large datasets. The StringBuilder method, while avoiding serialization overhead, requires manual handling of all data types and formatting details.

Functional Completeness

Json.NET provides the richest feature set, including custom serialization, circular reference handling, and date format control. JavaScriptSerializer offers relatively basic functionality but suffices for most simple scenarios.

Maintainability Considerations

Using mature serialization libraries (Json.NET or JavaScriptSerializer) generally provides better code maintainability, as they automatically handle complex issues like data type conversion and special character escaping.

Practical Application Scenarios

Web API Development

In ASP.NET Web API projects, converting DataTable to JSON format containing "records" keys facilitates frontend JavaScript processing:

public IHttpActionResult GetUserData()
{
    DataTable userData = GetDataFromDatabase();
    string jsonResult = ConvertDataTableToJsonWithRecords(userData, "UserId");
    return Ok(jsonResult);
}

Frontend Data Processing

The converted JSON data can be directly used on the frontend:

// JavaScript example
fetch('/api/userdata')
    .then(response => response.json())
    .then(data => {
        data.records.forEach(record => {
            console.log(`User ${record.Title}: ${record.viewCount} views`);
        });
    });

Best Practice Recommendations

Error Handling

In practical applications, appropriate error handling mechanisms should be implemented:

public string SafeConvertDataTableToJson(DataTable dt, string keyColumn)
{
    try
    {
        if (dt == null)
            throw new ArgumentNullException(nameof(dt));
            
        if (!dt.Columns.Contains(keyColumn))
            throw new ArgumentException($"Column {keyColumn} does not exist");
            
        return ConvertDataTableToJsonWithRecords(dt, keyColumn);
    }
    catch (Exception ex)
    {
        // Log error and return error information
        return $"{{\"error\":\"{ex.Message}\"}}";
    }
}

Performance Optimization

For large DataTables, consider using streaming processing or paginated conversion to reduce memory usage:

public IEnumerable<string> ConvertLargeDataTableToJsonChunks(DataTable dt, int chunkSize)
{
    for (int i = 0; i < dt.Rows.Count; i += chunkSize)
    {
        DataTable chunk = dt.Clone();
        int endIndex = Math.Min(i + chunkSize, dt.Rows.Count);
        
        for (int j = i; j < endIndex; j++)
        {
            chunk.ImportRow(dt.Rows[j]);
        }
        
        yield return ConvertDataTableToJsonWithRecords(chunk, "Id");
    }
}

Conclusion

DataTable to JSON conversion is a common requirement in .NET development. By appropriately selecting conversion methods and following best practices, efficient and reliable data exchange solutions can be constructed. In actual projects, prioritizing the use of the Json.NET library is recommended, as it offers significant advantages in performance, functionality, and community support.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.