Using a C# 7 tuple in an ASP.NET Core Web API Controller

It doesn’t work because named tuple names are not quite “real”, it’s mostly syntax sugar provided by compiler. If you look at ValueTuple set of types, by which named tuples are represented, you will see that they have properties like Item1, Item2 and so on.

Compiler will rewrite all your references to named tuple names to their real names (Item1 etc). For example you have this:

static void Create((string username, string password) usernameAndPassword) {
    Console.WriteLine(usernameAndPassword.username);
    Console.WriteLine(usernameAndPassword.password);
}

But when you compile that, what you really will have is this:

static void Create([TupleElementNames(new string[] {"username", "password"})] ValueTuple<string, string> usernameAndPassword)
{
  Console.WriteLine(usernameAndPassword.Item1);
  Console.WriteLine(usernameAndPassword.Item2);
}

Your names are now only in metadata attribute TupleElementNames, but not in code.

For that reason, when you post something like:

{"username": "x", "password": "y"}

to your action, asp.net cannot bind. But if you would post:

{"item1": "x", "item2": "y"}

then it will bind with no problems. You can write custom binder probably, which can use TupleElementNames attribute, but there is no reason to really. Just use separate parameters or real model as suggested in comments. Your action input parameters is not some throwaway thing. You might later want to validate them, generate documentation from the model and so on.

Leave a Comment