我正在使用 Code First 方法与 Entity Framework 一起创建 .NET Core WEB API 项目。我无法验证请求的输入,因为 ModelState 验证始终为真。
我的应用程序由 3 层组成。
- 数据访问层
- 业务逻辑层
- .NET 核心 API
DAL 中的示例数据模型:
public class Group
{
[Key]
[Required]
public long GroupId { get; set; }
[Required]
public string Name { get; set; }
[Required(AllowEmptyStrings = false)]
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public bool IsActive { get; set; }
}
对应的DTO:
public class GroupDto
{
public long GroupId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Controller 方法:
[HttpPost]
public IActionResult Post([FromBody] GroupDto groupDto)
{
Group group = _mapper.Map<Group>(groupDto);
if (!ModelState.IsValid)
{
return BadRequest();
}
_groupService.Add(group);
groupDto = _mapper.Map<GroupDto>(group);
return Ok(groupDto);
}
据我所知,在当前状态下 ModelState.IsValid 将始终返回 true,因为 GroupDto 没有通过 DataAnnotations 完成任何验证。
应如何验证 DTO?我想避免在两个地方重复相同的验证。是否应该创建额外的自定义 DtoValidator,或者我是否遗漏了一些东西,并且有办法执行这些验证。
最佳答案
模型状态验证将在传入的模型上进行,在您的例子中是 GroupDto。仅仅因为您最终映射到 Group 类与验证的工作方式无关。您将需要在 DTO 中重复验证属性。这确实重复了代码,但也允许您自定义规则,因为您可能希望也可能不希望在 DTO 中设置完全相同的规则。这方面的一个例子是您的主键。对于创建 (POST),您不一定希望 GroupId 成为传递给 Controller 的必填字段,因为数据库可能会自动生成该字段(取决于您的设置)。
如果您使用的是 ASP.Net Core 2.1 或更高版本,您现在还可以将 [ApiController] 属性应用于 Controller 类,它会自动应用模型验证规则。这消除了手动检查 ModelState.IsValid 的需要。如果模型无效,系统会自动返回 400 Bad Request。 ( https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-2.2#annotation-with-apicontroller-attribute )
关于c# - 使用 ModelState 验证 DTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55425609/