在我的API项目中,我有多个端点用于简单的CRUD操作。端点使用FluentValidation通过将验证器添加到DI并使用ModelState.IsValid
来验证提供的模型。
当只有一个模型作为参数时,ModelState.IsValid正常工作,但是一旦我有多个模型,那么只有第一个得到验证,下面的例子使这个问题变得有点cla:
我的UPDATE
端点操作需要2个参数(Id和模型):
public async Task<IActionResult> UpdateMedium([CustomizeValidator(RuleSet = ValidationClass.UPDATE)] [FromRoute] long id, [FromBody] Medium model)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
if (id != model.MediumID)
{
return this.BadRequest();
}
// Etc....
}
this.ModelState.IsValid
现在只验证第一个模型(Id),第二个模型得到忽略。
验证两种模型的最佳方法是什么?
Id参数显然非常简单,但无论如何我都为它制作了一个FluentValidation验证器(以防我们希望将来为它添加更多验证逻辑):
public class IdValidator : AbstractValidator<long>
{
public IdValidator()
{
RuleFor(r => r).NotEmpty().WithMessage("Id is empty.");
}
}
此外,Medium模型验证器如下所示:
public class MediumValidator : AbstractValidator<Medium>
{
public MediumValidator()
{
RuleSet(ValidationClass.CREATE, Create);
RuleSet(ValidationClass.UPDATE, Update);
}
private void Create()
{
RuleFor(r => r.InsertDateTime).Empty().WithMessage("{PropertyName} is not empty.");
RuleFor(r => r.InsertUserID).Empty().WithMessage("{PropertyName} is not empty.");
RuleFor(r => r.SolutionID).Empty().WithMessage("{PropertyName} is not empty.");
RuleFor(r => r.Name).NotEmpty().WithMessage("{PropertyName} is not filled in.");
RuleFor(r => r.Name).MaximumLength(100).WithMessage("The length of {PropertyName} must be {MaxLength} characters or fewer. You entered {TotalLength} characters.");
}
private void Update()
{
RuleFor(r => r.UpdateDateTime).Empty().WithMessage("{PropertyName} is not empty.");
RuleFor(r => r.UpdateUserID).Empty().WithMessage("{PropertyName} is not empty.");
RuleFor(r => r.MediumID).NotEmpty().WithMessage("{PropertyName} is empty.");
RuleFor(r => r.Name).NotEmpty().WithMessage("{PropertyName} is not filled in.");
RuleFor(r => r.Name).MaximumLength(100).WithMessage("The length of {PropertyName} must be {MaxLength} characters or fewer. You entered {TotalLength} characters.");
}
}
也许我只应该使用模型作为参数,然后只需要输入ID字段?
更新
在启动时设置FluentValidation:
services.AddMvc()
.AddFluentValidation(fv =>
{
fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
});
// Add fluent validators
services.AddTransient<IValidator<long>, IdValidator>();
services.AddTransient<IValidator<Medium>, MediumValidator>();
UPDATE2:
我正在使用swagger来测试端点(JSON输入)。
答案 0 :(得分:1)
目前我实施了一种不同的方法。对于UPDATE操作,我现在手动将Medium模型错误添加到ModelState
:
var validator = new MediumValidator();
var result = validator.Validate(model, ruleSet: ValidationClass.UPDATE);
result.AddToModelState(this.ModelState, null);
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
欢迎更好的解决方案!