如何在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
相关产品推荐
相关产品推荐

