Why the return value of ValueTuple is empty JSON?
Asked Answered
A

1

7

In .NET 5, I created a default webapi solution "WebApplication1", and I have an action in WeatherForecastController:

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

Why do I always get an empty JSON {}?

Abscise answered 28/7, 2021 at 2:53 Comment(0)
M
8

The problem is ASP.NET Core uses System.Text.Json for serialization. But it cannot handle (named) tuples:

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

This outputs an empty object {}.

Json.NET can serialize it, but with a caveat: it doesn't preserve tuple keys.

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

This outputs:

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

So your easiest option is to use a wrapper class if you want to preserve the keys:

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});
}

Or you could choose the hard way and write a custom serializer that takes tuple keys into account. But even that wouldn't work, because the reflection information doesn't include keys. My guess is that the compiler discards this info after resolving the keys.

Marismarisa answered 28/7, 2021 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.