如何将正文中的 null 传递到 asp.net 核心 3.1 中的端点
How to pass null in body to endpoint within asp.net core 3.1
我在 asp.net 核心 3.1 控制器中执行以下操作
[ApiController]
[Route("example")]
public class MyExampleController : ControllerBase
{
[HttpPost("{id}/value")]
public async Task<IActionResult> Post(string id, [FromBody] int? value)
=> Task.FromResult(Ok());
}
如果我 post int 的主体值(例如:1
、2
等...)
但是,我找不到获取传入的 null
值的方法。
如果我传入空主体或 null
主体,我将返回状态代码 400,并返回验证消息 A non-empty request body is required.
。
我还尝试将 value
参数更改为可选参数,默认值为 null
:
public async Task<IActionResult> Post(string id, [FromBody] int? value = null)
如何将 null 传递给此操作?
引用Automatic HTTP 400 responses
The [ApiController]
attribute makes model validation errors automatically trigger an HTTP 400 response
这将解释返回的响应。
删除 [ApiController]
以允许无效请求仍然进入控制器操作,并且如果具有该属性的附加功能对当前控制器不重要。
但是需要手动应用所需的功能
[Route("example")]
public class MyExampleController : ControllerBase {
[HttpPost("{id}/value")]
public async Task<IActionResult> Post(string id, [FromBody] int? value) {
if (!ModelState.IsValid) {
//...
return BadRequest(ModelState);
}
//...
return Ok();
}
}
似乎与JSON的单值传递方式有关。它需要一个值,而 null 只是简单地创建一个空的请求主体。你应该考虑像这样定义一个 class
public class MyInt{
public int Value { get; set; }
public bool IsNull { get; set; }
}
[ApiController]
[Route("example")]
public class MyExampleController : ControllerBase
{
[HttpPost("{id}/value")]
public IActionResult Post(string id, [FromBody]MyInt value)
{
if(value.IsNull){
}
else{
}
return Ok();
}
}
换句话说,当您 POST 时,您 post 不只是使用默认值。你可以像这样用另一种方式做到这一点
[HttpPost("{id}/value")]
public IActionResult Post(string id, [FromBody]int value)...
[HttpGet("{id}/value")]
public IActionResult Get(string id)...//use the default value here
终于弄明白了,非常感谢@Nkosi 和@KirkLarkin 帮助找到了这个问题。
在 Startup.cs
中将控制器配置到容器中时,我们只需要将默认的 mvc 选项更改为 AllowEmptyInputInBodyModelBinding
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(x => x.AllowEmptyInputInBodyModelBinding = true);
}
这样我们就可以将 null
传递到 post 的正文中并且它工作得很好。它还通过属性应用正常模型验证,而无需手动检查 ModelState:
public async Task<IActionResult> Post(string id,
[FromBody][Range(1, int.MaxValue, ErrorMessage = "Please enter a value bigger than 1")]
int? value = null)
我在 asp.net 核心 3.1 控制器中执行以下操作
[ApiController]
[Route("example")]
public class MyExampleController : ControllerBase
{
[HttpPost("{id}/value")]
public async Task<IActionResult> Post(string id, [FromBody] int? value)
=> Task.FromResult(Ok());
}
如果我 post int 的主体值(例如:1
、2
等...)
但是,我找不到获取传入的 null
值的方法。
如果我传入空主体或 null
主体,我将返回状态代码 400,并返回验证消息 A non-empty request body is required.
。
我还尝试将 value
参数更改为可选参数,默认值为 null
:
public async Task<IActionResult> Post(string id, [FromBody] int? value = null)
如何将 null 传递给此操作?
引用Automatic HTTP 400 responses
The
[ApiController]
attribute makes model validation errors automatically trigger an HTTP 400 response
这将解释返回的响应。
删除 [ApiController]
以允许无效请求仍然进入控制器操作,并且如果具有该属性的附加功能对当前控制器不重要。
但是需要手动应用所需的功能
[Route("example")]
public class MyExampleController : ControllerBase {
[HttpPost("{id}/value")]
public async Task<IActionResult> Post(string id, [FromBody] int? value) {
if (!ModelState.IsValid) {
//...
return BadRequest(ModelState);
}
//...
return Ok();
}
}
似乎与JSON的单值传递方式有关。它需要一个值,而 null 只是简单地创建一个空的请求主体。你应该考虑像这样定义一个 class
public class MyInt{
public int Value { get; set; }
public bool IsNull { get; set; }
}
[ApiController]
[Route("example")]
public class MyExampleController : ControllerBase
{
[HttpPost("{id}/value")]
public IActionResult Post(string id, [FromBody]MyInt value)
{
if(value.IsNull){
}
else{
}
return Ok();
}
}
换句话说,当您 POST 时,您 post 不只是使用默认值。你可以像这样用另一种方式做到这一点
[HttpPost("{id}/value")]
public IActionResult Post(string id, [FromBody]int value)...
[HttpGet("{id}/value")]
public IActionResult Get(string id)...//use the default value here
终于弄明白了,非常感谢@Nkosi 和@KirkLarkin 帮助找到了这个问题。
在 Startup.cs
中将控制器配置到容器中时,我们只需要将默认的 mvc 选项更改为 AllowEmptyInputInBodyModelBinding
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(x => x.AllowEmptyInputInBodyModelBinding = true);
}
这样我们就可以将 null
传递到 post 的正文中并且它工作得很好。它还通过属性应用正常模型验证,而无需手动检查 ModelState:
public async Task<IActionResult> Post(string id,
[FromBody][Range(1, int.MaxValue, ErrorMessage = "Please enter a value bigger than 1")]
int? value = null)