【问题标题】:ASP.NET Core - bind multiple controller parameters to bodyASP.NET Core - 将多个控制器参数绑定到正文
【发布时间】:2020-11-04 00:28:26
【问题描述】:

大家好

我正在使用 ASP.NET Core 3.1。我需要将控制器参数绑定到正文(它们太大而无法放入 URL)。我不希望只为单个方法创建 DTO(我也有多个端点,最终需要大量一次性 DTO)。这不可能开箱即用,所有当前的在线帮助似乎都集中在旧的 .NET Framework Web Api 上。

简单来说,给定以下控制器:

public class GreetController : ControllerBase
{
    public string Index(string firstname, string lastname) 
        => $"Hello {firstname} {lastname}";
}

以下 curl 命令:

curl -X GET --header "Content-Type: application/json" --data \
    "{\"firstname\":\"John\",\"lastname\":\"Doe\"}" https://[Url]/Greet/

应该返回Hello John Doe,但参数为空。添加[FromBody] 也不起作用。我需要它来为 Json 和 Xml 请求主体工作。我知道这可以通过 URI 参数来完成。但是,我有一些参数对于 URI 来说太大了,因此它们必须在请求正文中。

注意 2:请不要冗长解释为什么这不符合 REST

【问题讨论】:

  • 我觉得这里有两点。第一个是关于使用 GET 方法的 Body。你不能那样做。二是使用DTO,需要一个复杂的对象来解析body内容,因为FromBodyAttribute不能写在多个方法参数中。
  • 你可以在这里查看更多信息:docs.microsoft.com/en-us/aspnet/core/mvc/models/…

标签: c# asp.net-core .net-core


【解决方案1】:

这里有两件事你需要知道:

1.FromBody 无法处理获取请求。

2.不要将[FromBody] 应用于每个操作方法的多个参数。一旦请求流被输入格式化程序读取,就不能再被读取以绑定其他[FromBody] 参数。

如果你不想通过查询传递数据并且不想创建dtos,我建议你可以使用Newtonsoft.Json.Linq.JObject

public class GreetController : ControllerBase
{
    [HttpPost]
    public string Index([FromBody]JObject model)
    { 
        var firstname = model["firstname"].ToString();
        var lastname = model["lastname"].ToString();
        return $"Hello {firstname} {lastname}"; 
    }
}

Startup.cs:

services.AddControllers()
    .AddNewtonsoftJson();

关于如何在 ASP.NET Core 3.1 项目中使用Newtonsoft.Json

https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#use-newtonsoftjson-in-an-aspnet-core-30-mvc-project

结果:

另一种方法是自定义模型绑定器,您可以按照以下答案:

https://stackoverflow.com/a/60611928/11398810

【讨论】:

  • 我会查看自定义模型绑定器,它似乎可以满足我的需求。谢谢!
【解决方案2】:

这种情况对于 QueryString 请求来说似乎是理想的。示例:

GET:[Url]/Greet/?firstName=Rod&lastName=Ramirez

地点:

public class GreetController : ControllerBase
{
    public string Index([FromQuery] string firstname, string lastname) 
        => $"Hello {firstname} {lastname}";
}

未经测试,但这应该可以工作?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 2018-12-15
    • 1970-01-01
    • 2020-12-30
    • 2020-10-12
    相关资源
    最近更新 更多