在ASP.NET Core Web API控制器中使用C#7元组 [英] Using a C# 7 tuple in an ASP.NET Core Web API Controller

查看:219
本文介绍了在ASP.NET Core Web API控制器中使用C#7元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您知道为什么这样吗?

    public struct UserNameAndPassword
    {
        public string username;
        public string password;
    }


    [HttpPost]
    public IActionResult Create([FromBody]UserNameAndPassword usernameAndPassword)
    {
        Console.WriteLine(usernameAndPassword);
        if (this.AuthenticationService.IsValidUserAndPasswordCombination(usernameAndPassword.username, usernameAndPassword.password))
            return new ObjectResult(GenerateToken(usernameAndPassword.username));
        return BadRequest();
    }

但是当我用元组替换它时,这行不通吗?

But when I replace it with a tuple, this doesn’t work?

     [HttpPost]
    public IActionResult Create([FromBody](string username, string password) usernameAndPassword) //encrypt password?
    {
        Console.WriteLine(usernameAndPassword);
        if (this.AuthenticationService.IsValidUserAndPasswordCombination(usernameAndPassword.username, usernameAndPassword.password))
            return new ObjectResult(GenerateToken(usernameAndPassword.username));
        return BadRequest();
    }

usernameAndPassword.username和.password均为空.

usernameAndPassword.username and .password are both null.

是否不允许在控制器中使用元组?

Are you not allowed to use tuples in a controller?

推荐答案

它不起作用,因为命名的元组名称不是很真实",它主要是编译器提供的语法糖.如果查看ValueTuple类型集(表示命名元组),您将看到它们具有诸如Item1Item2等的属性.

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.

编译器会将您对命名元组名称的所有引用重写为它们的真实名称(Item1等).例如,您有以下内容:

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

您的姓名现在仅在元数据属性TupleElementNames中,而在代码中没有.

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"}

对于您的操作,asp.net无法绑定.但是,如果您要发布:

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

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

然后它将毫无问题地绑定.您可能可以编写可使用TupleElementNames属性的自定义活页夹,但是没有理由这么做.只需使用注释中建议的单独参数或实际模型即可.您的动作输入参数并不是一成不变的东西.您稍后可能要验证它们,从模型生成文档,等等.

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.

这篇关于在ASP.NET Core Web API控制器中使用C#7元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆