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

如何为ASP.NET Web.API定制符合要求的JSON输出格式

解决方案:手动组装嵌套JSON结构

针对你遇到的问题——从SQL存储过程获取扁平化数据后,无法生成外层字段唯一、内层嵌套的JSON响应,以下是具体实现步骤:

1. 定义匹配目标格式的实体类

先创建对应目标JSON结构的C#实体,明确外层和嵌套层的属性:

// 外层购物车响应实体
public class CartResponse
{
    public string CartId { get; set; }
    public string UserId { get; set; }
    public DateTime CreateTime { get; set; }
    public List<CartItem> Items { get; set; } = new List<CartItem>();
}

// 内层购物车商品项实体
public class CartItem
{
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
}

2. 读取存储过程数据并手动组装嵌套结构

由于存储过程返回的是扁平化数据(每个商品对应一行,重复CartId等外层字段),通过Linq分组将相同购物车的商品聚合到一起:

public CartResponse GetCartData(string targetCartId)
{
    CartResponse cartResult = null;
    // 替换为你的数据库连接字符串
    var connectionString = "Server=YOUR_SERVER;Database=YOUR_DB;Trusted_Connection=True;";
    
    using (var sqlConn = new SqlConnection(connectionString))
    {
        sqlConn.Open();
        using (var cmd = new SqlCommand("YOUR_STORED_PROCEDURE_NAME", sqlConn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            // 添加存储过程所需参数
            cmd.Parameters.Add("@CartId", SqlDbType.VarChar).Value = targetCartId;

            using (var reader = cmd.ExecuteReader())
            {
                // 先读取所有扁平化数据到临时集合
                var flatData = new List<(string CartId, string UserId, DateTime CreateTime, string ProductId, string ProductName, int Quantity)>();
                while (reader.Read())
                {
                    flatData.Add(
                        (
                            CartId: reader.GetString(reader.GetOrdinal("CartId")),
                            UserId: reader.GetString(reader.GetOrdinal("UserId")),
                            CreateTime: reader.GetDateTime(reader.GetOrdinal("CreateTime")),
                            ProductId: reader.GetString(reader.GetOrdinal("ProductId")),
                            ProductName: reader.GetString(reader.GetOrdinal("ProductName")),
                            Quantity: reader.GetInt32(reader.GetOrdinal("Quantity"))
                        )
                    );
                }

                // 分组组装嵌套结构
                if (flatData.Any())
                {
                    // 按CartId、UserId、CreateTime分组(这些是外层唯一字段)
                    var groupedData = flatData.GroupBy(x => new { x.CartId, x.UserId, x.CreateTime });
                    var firstGroup = groupedData.First();
                    
                    cartResult = new CartResponse
                    {
                        CartId = firstGroup.Key.CartId,
                        UserId = firstGroup.Key.UserId,
                        CreateTime = firstGroup.Key.CreateTime,
                        Items = firstGroup.Select(item => new CartItem
                        {
                            ProductId = item.ProductId,
                            ProductName = item.ProductName,
                            Quantity = item.Quantity
                        }).ToList()
                    };
                }
            }
        }
    }
    return cartResult;
}

3. 在API控制器中返回组装好的实体

在Web API控制器方法中调用上述方法,直接返回实体即可自动序列化为符合要求的JSON:

[HttpGet("cart/{cartId}")]
public IHttpActionResult GetCart(string cartId)
{
    var cartResponse = GetCartData(cartId);
    if (cartResponse == null)
    {
        return NotFound();
    }
    return Ok(cartResponse);
}

为什么之前的方法不生效?

  • SQL FOR JSON:如果存储过程返回扁平结果,FOR JSON AUTO会重复外层字段,FOR JSON PATH需要复杂的嵌套关联处理,灵活性不如代码层组装;
  • 直接返回数据集/列表:这些都是扁平化结构,无法自动生成嵌套的JSON层级,必须手动聚合数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:56:14