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

C# ASP.NET Core Web API返回空对象数组:数据存在却无法正常输出

问题分析与解决方法

核心问题1:值元组的JSON序列化缺陷

你返回的List<(string listName, DateTime timeCreated)>是值元组列表,ASP.NET Core默认的System.Text.Json序列化器无法识别值元组的命名语法糖——运行时值元组的实际字段为Item1、Item2,且这些字段属于内部私有类型,序列化器无法读取,最终输出空对象{}。

核心问题2:HttpGet使用[FromBody]不符合HTTP规范

HttpGet请求的设计逻辑是通过URL传递参数,而非请求体。虽然部分客户端支持GET带请求体,但这违反HTTP标准,可能引发兼容性问题(如部分代理、网关会丢弃GET请求体)。


解决方案

1. 替换值元组为强类型DTO(推荐)

创建专门的DTO类承载返回数据,序列化器可正确识别属性名:

// 定义DTO类
public class ListInfoDto
{
    public string ListName { get; set; }
    public DateTime TimeCreated { get; set; }
}

修改服务层方法的返回类型与逻辑:

public async Task<List<ListInfoDto>> LoadAllLists(string targetUserId)
{
    using (var connection = new SqlConnection(_configuration.GetConnectionString("DefaultConnection")))
    {
        connection.Open();
        using (var command = new SqlCommand("SELECT listName, timeCreated FROM [dbo].[jsonList] WHERE userid = @userid", connection))
        {
            command.Parameters.AddWithValue("@userid", targetUserId);

            using (var reader = await command.ExecuteReaderAsync())
            {
                var responseList = new List<ListInfoDto>();

                while (await reader.ReadAsync())
                {
                    responseList.Add(new ListInfoDto
                    {
                        ListName = reader.GetString(0),
                        TimeCreated = reader.GetDateTime(1)
                    });
                }
                return responseList;
            }
        }
    }
}

2. 修正HttpGet的参数传递方式

将userId改为URL查询参数或路由参数:

方式一:查询参数

[HttpGet("getAllLists")]
public async Task<IActionResult> LoadAllLists([FromQuery] string userId)
{
    var lists = await _listDataHandlingService.LoadAllLists(userId);
    return Ok(lists);
}

请求URL示例:/api/RequestHandling/getAllLists?userId=xxx

方式二:路由参数

[HttpGet("getAllLists/{userId}")]
public async Task<IActionResult> LoadAllLists(string userId)
{
    var lists = await _listDataHandlingService.LoadAllLists(userId);
    return Ok(lists);
}

请求URL示例:/api/RequestHandling/getAllLists/xxx


旧项目能正常工作的原因

大概率旧项目使用了Newtonsoft.Json(Json.NET)作为序列化器,Json.NET对值元组的命名元素有特殊处理,可将其序列化为对应命名属性;而当前项目默认使用System.Text.Json,无此特性。若坚持使用值元组,可切换回Newtonsoft.Json,但仍推荐使用DTO,代码可读性与可维护性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:32:04