zhusp
zhusp

Reputation: 183

Why the return value of ValueTuple is empty JSON?

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 {}?

Upvotes: 7

Views: 1419

Answers (1)

abdusco
abdusco

Reputation: 11091

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.

Upvotes: 8

Related Questions