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

如何在C# Web API中获取存储过程数据且返回值不含Table字段

解决DataSet序列化返回嵌套Table结构的问题

没问题,我懂你要的效果——直接返回纯数组而不是带Table键的嵌套JSON。原因很简单:默认情况下,DataSet的序列化会把内部的DataTable包装在以表名为键的对象里(这里你的表默认叫Table)。要改成你要的格式,只需要把DataTable里的行数据直接提取出来返回就行,不用整个DataSet。

这里有两种常用的实现方式,按需选择:

方式1:直接返回DataTable(简单快速)

如果你的API序列化器能正确处理DataTable(ASP.NET Web API默认的JsonMediaTypeFormatter是可以的),直接返回第一个表就行:

DataSet ds = new DataSet();
using (SqlConnection con = new SqlConnection("data source=.; database=GiveTradeApp; integrated security=true;")) {
    SqlCommand cmd = new SqlCommand("sp_get_products_by_user", con);
    cmd.Parameters.Add("user_id", SqlDbType.Int).Value = id;
    cmd.CommandType = CommandType.StoredProcedure;
    con.Open();
    SqlDataAdapter adp = new SqlDataAdapter();
    adp.SelectCommand = cmd;
    adp.Fill(ds);
}

// 关键修改:返回第一个DataTable而不是整个DataSet
var message = Request.CreateResponse(HttpStatusCode.OK, ds.Tables[0]);
return message;

这样返回的JSON就是你要的纯数组格式,每个元素对应一行数据。

方式2:转换成匿名类型/字典(更灵活可控)

如果需要对返回的字段做自定义(比如重命名、过滤空值),可以把行数据转换成匿名对象或者字典列表:

匿名类型(推荐,类型安全)

DataSet ds = new DataSet();
using (SqlConnection con = new SqlConnection("data source=.; database=GiveTradeApp; integrated security=true;")) {
    // 原数据库操作代码不变
    SqlCommand cmd = new SqlCommand("sp_get_products_by_user", con);
    cmd.Parameters.Add("user_id", SqlDbType.Int).Value = id;
    cmd.CommandType = CommandType.StoredProcedure;
    con.Open();
    SqlDataAdapter adp = new SqlDataAdapter();
    adp.SelectCommand = cmd;
    adp.Fill(ds);
}

// 把DataTable行转换成匿名对象列表
var products = ds.Tables[0].AsEnumerable()
    .Select(row => new {
        ProductId = row.Field<int>("ProductId"), // 替换成你的实际列名
        ProductName = row.Field<string>("ProductName"),
        Price = row.Field<decimal>("Price"),
        // 按需添加其他列
    });

var message = Request.CreateResponse(HttpStatusCode.OK, products);
return message;

字典列表(适合动态列)

如果你的存储过程返回的列不固定,用字典可以自动适配所有列:

DataSet ds = new DataSet();
using (SqlConnection con = new SqlConnection("data source=.; database=GiveTradeApp; integrated security=true;")) {
    // 原数据库操作代码不变
    SqlCommand cmd = new SqlCommand("sp_get_products_by_user", con);
    cmd.Parameters.Add("user_id", SqlDbType.Int).Value = id;
    cmd.CommandType = CommandType.StoredProcedure;
    con.Open();
    SqlDataAdapter adp = new SqlDataAdapter();
    adp.SelectCommand = cmd;
    adp.Fill(ds);
}

// 转换成字典列表,自动映射所有列
var rows = ds.Tables[0].AsEnumerable()
    .Select(row => ds.Tables[0].Columns.Cast<DataColumn>()
        .ToDictionary(col => col.ColumnName, col => row[col] ?? DBNull.Value));

var message = Request.CreateResponse(HttpStatusCode.OK, rows);
return message;

为什么原代码会返回嵌套结构?

DataSet本质是一个包含多个DataTable的集合,默认的JSON序列化会把每个DataTable作为一个属性(键就是表名,默认是Table、Table1这样),所以才会出现{"Table": [...]}的格式。直接返回单个DataTable或者它的行数据,就能得到你想要的纯数组JSON。

内容的提问来源于stack exchange,提问作者Dante Gulapa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:48:43