You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#获取REST API数据并写入SQL表时的JSON反序列化报错问题求助

解决C#中嵌套JSON反序列化DataTable失败并插入SQL的问题

Hey Edi, let's break down what's going wrong and fix this step by step!

问题原因

你遇到的JsonSerializationException是因为API返回的JSON结构是嵌套的:content数组里的每个元素不是直接包含name/age/date的平面对象,而是包裹在一个user对象里。DataTable无法直接解析这种嵌套结构,它期望每个数组元素都是直接的键值对(对应表格的列和值),所以才会报错"Unexpected JSON token when reading DataTable: StartObject"。

解决方案步骤

我们先通过实体类来正确解析嵌套的JSON,再提取数据插入SQL,同时优化数据库操作的效率。

1. 定义对应JSON结构的实体类

先创建几个简单的类来匹配API返回的JSON,这样反序列化会更清晰、不容易出错:

// 对应每个user的具体数据
public class UserData
{
    public string name { get; set; }
    public string age { get; set; }
    public string date { get; set; }
}

// 对应content数组里的每个元素(包裹user的对象)
public class ContentItem
{
    public UserData user { get; set; }
}

// 对应整个API返回的JSON结构
public class ApiResponse
{
    public List<ContentItem> content { get; set; }
    // 如果需要用到其他字段(比如ReturnCode、@count),可以在这里添加对应的属性
}

2. 修改API调用与反序列化代码

替换你原来错误的反序列化代码,改用实体类来解析JSON:

protected void btnAPI_OnClick(object sender, EventArgs e)
{
    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

    using (WebClient client = new WebClient())
    {
        client.Credentials = new NetworkCredential(username, password);
        string json = client.DownloadString("https://XXXX/XXXX001?view=expand");

        // 反序列化到我们定义的ApiResponse类,正确解析嵌套结构
        var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(json);

        // 提取所有user数据,得到一个UserData的列表
        var userList = apiResponse.content.Select(item => item.user).ToList();

        // 插入SQL表(优化后的数据库操作)
        InsertUsersToSql(userList);
    }
}

3. 优化SQL插入方法

原来的代码在循环里重复打开/关闭数据库连接,这会降低效率。我们用using语句自动管理连接生命周期,同时避免重复代码:

private void InsertUsersToSql(List<UserData> userList)
{
    // 替换成你的数据库连接字符串,或者复用你的connection()方法返回的连接
    string connectionString = "你的SQL连接字符串";

    foreach (var user in userList)
    {
        using (SqlConnection sqlConn = new SqlConnection(connectionString))
        {
            string qry = "INSERT INTO myTable (name, age, date) VALUES(@name, @age, @date)";
            sqlConn.Open();

            using (SqlCommand cmd = new SqlCommand(qry, sqlConn))
            {
                // 添加参数,避免SQL注入
                cmd.Parameters.AddWithValue("@name", user.name);
                cmd.Parameters.AddWithValue("@age", user.age);
                
                // 注意:如果SQL表的date字段是datetime类型,需要把字符串转成DateTime对象
                cmd.Parameters.AddWithValue("@date", DateTime.Parse(user.date));

                cmd.ExecuteNonQuery();
            }
            // using块结束后,连接会自动关闭并归还到连接池
        }
    }
}

额外优化建议(可选)

如果你的API返回大量数据(比如几百条以上),用SqlBulkCopy批量插入会比循环插入高效得多。你可以把userList转换成DataTable,然后批量写入:

private void BulkInsertUsersToSql(List<UserData> userList)
{
    string connectionString = "你的SQL连接字符串";

    // 把userList转换成DataTable
    DataTable dt = new DataTable();
    dt.Columns.Add("name", typeof(string));
    dt.Columns.Add("age", typeof(string));
    dt.Columns.Add("date", typeof(DateTime));

    foreach (var user in userList)
    {
        dt.Rows.Add(user.name, user.age, DateTime.Parse(user.date));
    }

    // 批量插入
    using (SqlConnection sqlConn = new SqlConnection(connectionString))
    {
        sqlConn.Open();
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConn))
        {
            bulkCopy.DestinationTableName = "myTable";
            // 映射列名(如果DataTable列名和SQL表列名一致,这步可以省略)
            bulkCopy.ColumnMappings.Add("name", "name");
            bulkCopy.ColumnMappings.Add("age", "age");
            bulkCopy.ColumnMappings.Add("date", "date");

            bulkCopy.WriteToServer(dt);
        }
    }
}

关键注意点

  • 日期类型转换:如果你的SQL表中date字段是datetime/datetime2类型,一定要把JSON里的字符串转换成DateTime对象,避免插入失败或格式错误。
  • SQL注入防护:始终使用参数化查询(AddWithValue),不要直接拼接SQL字符串。
  • 连接管理:用using语句管理SqlConnection和SqlCommand,确保资源自动释放,避免连接泄漏。

内容的提问来源于stack exchange,提问作者Edi Isma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 02:37:39