Sto*_*-BE 5 c# model-binding asp.net-core asp.net-core-2.2
这是我潜伏在这里多年后的第一个问题,所以我希望我不会违反任何规则。
在我的某些ASP.NET Core API的POST方法中,我希望客户端可以在POST请求的正文中仅提供要更新的属性。
这是我的代码的简化版本:
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public sealed class FooController : ControllerBase
{
public async Task<IActionResult> UpdateFooAsync(Guid fooGuid, [FromBody]UpdateFooModel model)
{
... Apply updates for specified properties, checking for authorization where needed...
return Ok();
}
}
public sealed class UpdateFooModel
{
[BindProperty] public int? MaxFoo { get; set; }
[BindProperty] public int? MaxBar { get; set; }
}
public sealed class Foo
{
public int? MaxFoo { get; set; }
public int? MaxBar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
MaxBar和MaxFoo都是可为空的整数值,其中null值表示没有最大值。
我正在尝试让客户端将以下内容发送到此端点:
将MaxBar设置为null,并将MaxFoo设置为10
{
"maxBar": null,
"maxFoo": 10
}
Run Code Online (Sandbox Code Playgroud)将MaxBar设置为null,而不接触MaxFoo
{ "maxBar": null }
Run Code Online (Sandbox Code Playgroud)将MaxBar更新为5,不要触摸MaxFoo
{ "maxBar": 5 }
Run Code Online (Sandbox Code Playgroud)在我的方法UpdateFooAsync中,我只想更新在请求中指定的属性。
但是,当发生模型绑定时,未指定的属性将设置为其默认值(null对于可空类型)。
找出值是显式设置为null(应设置为null)还是在请求中不存在(不应该更新)的最佳方法是什么?
我尝试检查ModelState,但是它不包含“模型”的键,仅包含Guid类型参数。
当然,任何其他解决核心问题的方法也将受到欢迎。
谢谢!
根据 @russ-w 的建议(谢谢!)在这里回答我自己的问题:通过在每个可选属性的设置器中标记 bool 属性,我们可以查明是否提供了它。
public sealed class UpdateFooModel
{
private int? _maxFoo;
private int? _maxBar;
[BindProperty]
public int? MaxFoo
{
get => _maxFoo;
set
{
_maxFoo = value;
MaxFooSet = true;
}
}
public bool MaxFooSet { get; private set; }
[BindProperty]
public int? MaxBar
{
get => _maxBar;
set
{
_maxBar = value;
MaxBarSet = true;
}
}
public bool MaxBarSet { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
当然,仍然欢迎进一步的改进或其他解决方案!