即使请求正文中缺少属性,也会执行 .NET Core WebApi 操作



我的.NET Core 3.1 WebApi控制器PUT操作被找到并执行,即使它不应该。我在 [FromBody] 参数中有 2 个属性的请求数据对象。但是,如果我在请求 Body 中使用完全不同的属性调用此路由,或者根本没有属性 - 它似乎没问题并且执行了 Action,只有属性对其类型具有默认值。我预计 400 个错误请求。

public class UpdateLogRequestData
{
[Required]
public int Records { get; set; }
[Required]
public int LogStatusId { get; set; }
}

控制器操作:

[HttpPut]
[Route("{logId:int}")]
public IActionResult UpdateLog(
[FromRoute] int logId,
[FromBody] UpdateLogRequestData requestData)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
...
}

后来我尝试添加 [必需] 属性和 ModelState 验证,当我注意到即使通过"错误请求"执行操作 - 即具有错误命名属性的请求时。UpdateLogRequestData 中的属性只有 0 作为其值(int 默认值(。

这是危险的行为,因为我更新数据库中的记录。现在,如果有人发送没有记录和 LogStatusId 属性的请求,数据库将使用零更新。 为什么控制器不检查它?这是我第一次看到这样的东西。为什么在这种情况下没有发生错误请求?

因此,在深入研究Microsoft文档后,我发现Web API中的验证自.NET Core 3版本以来已更改。对于那些有相同问题的人来说,这里是ti的工作原理。

Web API 控制器不必检查 ModelState.IsValid,如果它们 具有 [ApiController] 属性。在这种情况下,自动 HTTP 当模型状态为 无效。有关详细信息,请参阅自动 HTTP 400 响应。

服务器上的[必需]验证。在服务器上,所需值为 如果属性为 null,则视为缺失。不可为空的字段为 始终有效,并且 [必需] 属性的错误消息永远不会 显示。

但是,不可为空属性的模型绑定可能会失败,从而导致 在错误消息中,例如值"无效。要指定 用于服务器端验证不可为空类型的自定义错误消息, 您有以下选项:

使字段可为空(例如,十进制?而不是十进制(。 可为 null 的值类型被视为标准可为 null 的类型。

指定模型绑定要使用的默认错误消息,如 如以下示例所示:

services.AddRazorPages()
.AddMvcOptions(options =>
{
options.MaxModelValidationErrors = 50;
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");
});
services.AddSingleton<IValidationAttributeAdapterProvider,
CustomValidationAttributeAdapterProvider>();

见行

options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");

使这些值类型可为空,以便在请求正文中省略时它们不会默认为非空默认值。

public class UpdateLogRequestData {
[Required]
public int? Records { get; set; }
[Required]
public int? LogStatusId { get; set; }
}

最新更新