【问题标题】:ASP.NET core - how to pass optional [FromBody] parameter?ASP.NET 核心 - 如何传递可选的 [FromBody] 参数?
【发布时间】:2021-09-13 08:30:18
【问题描述】:

如何在 ASP.NET Core (5.0) 中传递可选(可为空)[FromBody] 参数?如果我没有在我的请求中发送正文,我会收到 415 Unsupported Media Type 错误。这可以配置吗?如果可以,如何在控制器或操作上而不是在应用程序级别上进行配置?我认为它必须与模型验证有关,但不确定。谢谢。

[HttpGet("[action]")]
public async Task<IActionResult> GetElementsAsync([FromBody] IEnumerable<int> elements = default)
{
  var result = await dataService.GetData(elements);
  return Ok(result);
}

编辑:澄清一下:

这是典型的场景,它可以正常工作:

但是通过空的身体会立即返回 415 甚至没有采取行动:

【问题讨论】:

    标签: asp.net-core controller


    【解决方案1】:

    只需在您的请求标头中添加内容类型。没有content-type:application/json,当body为空时会出现415

    您的控制器没有变化。我这边测试没问题。

    我创建了一个新的 asp.net core 5 api 项目,这是我的控制器:

    using Microsoft.AspNetCore.Mvc;
    using System.Collections.Generic;
    
    namespace WebApi_net5.Controllers
    {
        public class HomeController : ControllerBase
        {
            [HttpGet("[action]")]
            public string GetElementsAsync([FromBody] IEnumerable<int> elements = default)
            {
                return "value";
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以在这里找到解决方案:
      https://github.com/pranavkm/OptionalBodyBinding

      来自github上的这个问题:
      https://github.com/dotnet/aspnetcore/issues/6878

      从 .net Core 5 开始,您可以使用这个:

      public async Task<IActionResult> GetElementsAsync([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] IEnumerable<int> elements = default)
      ...
      

      也需要(根据 Pawel 的经验):

      services.AddControllers(options =>{options.AllowEmptyInputInBodyModelBinding = true;})
      

      【讨论】:

      • 此解决方案是否仍需要创建自定义过滤器?我在 .NET core 5.0 上,只是添加 (EmptyBodyBehavior = EmptyBodyBehavior.Allow) 并没有改变行为。
      • 应该在没有自定义过滤器的情况下可用。检查全局设置。 GitHub 中的文档和 ms doc
      • 我尝试添加可空引用类型注释(IEnumerable&lt;int&gt;? - 有人声称这对他们有用:github.com/dotnet/aspnetcore/issues/30690),使用services.AddControllers(options =&gt;{options.AllowEmptyInputInBodyModelBinding = true;}) 配置服务并使用services.Configure&lt;ApiBehaviorOptions&gt;(options =&gt; {options.SuppressModelStateInvalidFilter = true;}); 禁用模型验证这些都不起作用://
      • 帕维尔干得好!
      • 我认为 [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] 期望用户发送空正文(顾名思义),而不仅仅是不发送任何正文。没有正文的消息与没有正文的消息之间的区别如下:curl --location --request POST 'https://localhost:44349/MyController/MyAction' vs curl --location --request POST 'https://localhost:44349/MyController/MyAction' \ --data-raw ''
      【解决方案3】:

      使用 ASP.NET Core 3.1,我可以通过实现 Nicola 的建议来允许 nullable 可选 参数:

      services.AddControllers(options =>{options.AllowEmptyInputInBodyModelBinding = true;})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-05
        • 1970-01-01
        • 2019-11-29
        • 1970-01-01
        • 2021-03-19
        • 1970-01-01
        • 2016-11-16
        • 2019-11-20
        相关资源
        最近更新 更多