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.