为什么ValueTuple的返回值为空JSON?

zhu*_*usp 7 c# value-type asp.net-core asp.net-core-webapi

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

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

Run Code Online (Sandbox Code Playgroud)

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

abd*_*sco 7

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

var result = (Message: "hello", Success: true);
var json = JsonSerializer.Serialize(result);
Console.WriteLine(json);
Run Code Online (Sandbox Code Playgroud)

这输出一个空对象{}

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

var result = (Message: "hello", Success: true);
var json = JsonConvert.SerializeObject(result);
Console.WriteLine(json);
Run Code Online (Sandbox Code Playgroud)

这输出:

{"Item1":"hello","Item2":true}
Run Code Online (Sandbox Code Playgroud)

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

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});
}
Run Code Online (Sandbox Code Playgroud)

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