簡體   English   中英

在 ASP.NET Core Web API 控制器中使用 C# 7 元組

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

你知道為什么會這樣嗎:

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

但是當我用元組替換它時,這不起作用?

[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都是空的。

不允許在控制器中使用元組嗎?

它不起作用,因為命名元組名稱不太“真實”,它主要是編譯器提供的語法糖。 如果您查看表示命名元組的ValueTuple類型集,您將看到它們具有Item1Item2等屬性。

編譯器會將您對命名元組名稱的所有引用重寫為它們的真實名稱( 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屬性,但沒有理由真的這樣做。 只需按照評論中的建議使用單獨的參數或真實模型。 你的動作輸入參數不是一次性的東西。 您稍后可能想要驗證它們,從模型生成文檔等等。

你可以使用這個包。 此包將 json 正文綁定到您的模型。

Github 倉庫

安裝

//Nuget
Install-Package M6T.Core.TupleModelBinder -Version 1.0.0

//dotnet cli
dotnet add package M6T.Core.TupleModelBinder --version 1.0.0

用法

修改startup.cs之類的

using M6T.Core.TupleModelBinder;
....

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc(options =>
  {
      options.ModelBinderProviders.Insert(0, new TupleModelBinderProvider());
  });
}

發布請求正文

{
  "user" : {
    "Name":"Test",
    "Surname":"Test2",
    "Email":"example@example.com"
  },
  "someData" : "If you like it, you put a data on it"
}

在你的控制器中使用它

[HttpPost]
public IActionResult CreateUser((User user, string someData) request)
{
    using (var db = new DBContext())
    {
        var newUser = db.Users.Add(request.user);
        db.SaveChanges();
        return Json(new { userId = request.user.Id, someData = request.someData});
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM