为什么webapi中valuetuple的返回值为空json

问题描述

在 dotnet5 中,我创建了一个认的 webapi 解决方案“WebApplication1”,并且我在 WeatherForecastController 中有一个操作。

        [HttpGet]
        [Route("[action]")]
        public (bool,string) test()
        {
            return (true,"have a test!");
        }

为什么我总是得到一个空的 JSON {}。

解决方法

问题是 ASP.NET Core 使用 System.Text.Json 进行序列化。但它不能处理(命名)元组:

var result = (Message: "hello",Success: true);
var json = JsonSerializer.Serialize(result);
Console.WriteLine(json);

这会输出一个空对象 {}

Json.NET 可以序列化它,但有一个警告:它不保留元组键。

var result = (Message: "hello",Success: true);
var json = JsonConvert.SerializeObject(result);
Console.WriteLine(json);

输出:

{"Item1":"hello","Item2":true}

因此,如果您想保留密钥,最简单的选择是使用包装类:

public class Result<T>
{
    public T Data { get; set; }
    public bool Success { get; set; }
}

[HttpGet]
public async Task<ActionResult<Result<string>>> Hello(CancellationToken cancellationToken)
{
    // ...
    return Ok(new Result<string>{Data = "hello",Success = true});
}

或者您可以选择困难的方式并编写一个考虑元组键的自定义序列化程序。但即使这样也行不通,因为反射信息不包括键。我的猜测是编译器在解析密钥后会丢弃这些信息。

,

您所做的应该是一种 Tuple<T1,T2>。更改您的代码,如下所示:

[HttpGet]
[Route("[action]")]
public Tuple<bool,string> Test()
{
    return new Tuple<bool,string>(true,"have a test!");
}