Это не работает, потому что именованные имена кортежей не совсем "настоящие", это в основном синтаксический сахар, предоставляемый компилятором. Если вы посмотрите на ValueTuple
набор типов, в котором представлены именованные кортежи, вы увидите, что они имеют свойства, такие как Item1
, Item2
и т. Д.
Компилятор перепишет все ваши ссылки на именованные имена кортежей на их настоящие имена (Item1
и т. Д.). Например, у вас есть это:
static void Create((string username, string password) usernameAndPassword) {
Console.WriteLine(usernameAndPassword.username);
Console.WriteLine(usernameAndPassword.password);
}
Но когда вы скомпилируете это, у вас действительно будет следующее:
static void Create([TupleElementNames(new string[] {"username", "password"})] ValueTuple<string, string> usernameAndPassword)
{
Console.WriteLine(usernameAndPassword.Item1);
Console.WriteLine(usernameAndPassword.Item2);
}
Ваши имена теперь есть только в атрибуте метаданных TupleElementNames
, но не в коде.
По этой причине, когда вы публикуете что-то вроде:
{"username": "x", "password": "y"}
к вашему действию asp.net не может привязаться. Но если вы отправите:
{"item1": "x", "item2": "y"}
тогда он будет связываться без проблем. Возможно, вы можете написать пользовательское связующее, которое может использовать атрибут TupleElementNames
, но для этого нет никаких оснований. Просто используйте отдельные параметры или реальную модель, как это предлагается в комментариях. Ваши входные параметры действий не являются чем-то одноразовым. Позже вы можете захотеть проверить их, сгенерировать документацию из модели и т. Д.