FluentValidation 不适用于外部模型对象的集合
FluentValidation not working on collection of outer model objects
我无法让 FluentValidation 处理一组对象。我的控制器 POST 操作采用 IEnumerable 对象,如下所示。当我 post 执行单个 EventInputDto
且格式不正确的 Url
属性 的操作时,我的验证成功进行。当我 post 到 EventInputDto
的集合时,它不起作用并且没有验证。
如果我使用常规 MVC 属性(即必需/电子邮件),它们将与集合以及单个对象一起使用。我如何让它与 FluentValidation 一起使用?我没有使用内部集合,所以我不确定为什么它不能按预期工作。
public async Task<IActionResult> CreateEventCollection([FromBody] IEnumerable<EventInputDto> events)
{
if (!ModelState.IsValid)
{
return UnprocessableEntity(ModelState); //does not work
}
}
我的验证器是使用泛型设置的,因为我使用单独的模型进行输入和更新。
public class EventManipulationValidator<T> : AbstractValidator<T> where T : EventManipulationDto
{
public EventManipulationValidator()
{
RuleFor(manipulationDto => manipulationDto.Title).NotNull().WithMessage("Title cannot be blank")
.Length(1, 50);
RuleFor(manipulationDto => manipulationDto.Message).NotNull().WithMessage("Message cannot be blank")
.Length(1, 1000);
RuleFor(manipulationDto => manipulationDto.ScheduledTime).NotNull().WithMessage("Scheduled Time cannot be blank");
RuleFor(inputDto => inputDto.Url).Matches(@"https://.*windows\.net.*").WithMessage("The url must be valid and stored on Azure");
}
}
由于我的 CreateEventCollection 操作接受了 EventInputDto 的 IEnumerable,因此我的 EventInputDto 验证器设置如下:
public class EventInputValidator : EventManipulationValidator<EventInputDto>
{
public EventInputValidator()
{
//all property validators are inherited from EventManipulationValidator
}
}
public class EventInputCollectionValidator : AbstractValidator<IEnumerable<EventInputDto>>
{
public EventInputCollectionValidator()
{
RuleForEach(p => p).SetValidator(new EventManipulationValidator<EventInputDto>());
}
}
以下是我的模型供参考:
EventManipulationDto
public abstract class EventManipulationDto
{
public string Title { get; set; }
public string Message { get; set; }
public string Url { get; set; }
public DateTime? ScheduledTime { get; set; }
}
EventInputDto
public class EventInputDto : EventManipulationDto
{
//all properties inherited from base class
}
在查看了项目 GitHub 的 open/closed 个问题列表后,似乎我的方法并非全部都是必需的。不需要我的 EventInputCollectionValidator。 FluentValidation 不再需要像我上面定义的那样显式定义 IEnumerable 验证器。
定义一个基本的 AbstractValidator 就足够了,或者在我的例子中是一个从父 class 继承的验证器。
唯一需要让它工作的改变是在我的 startup.cs 注册 fluentvalidation 时。我需要明确添加 ImplicitlyValidateChildProperties = true
。没有意识到这是必需的,因为我认为这是为了验证子 属性 集合而不是父集合对象。现在完美运行。
.AddFluentValidation(fv => {
fv.RunDefaultMvcValidationAfterFluentValidationExecutes = true;
fv.RegisterValidatorsFromAssemblyContaining<Startup>();
fv.ImplicitlyValidateChildProperties = true;
});
我无法让 FluentValidation 处理一组对象。我的控制器 POST 操作采用 IEnumerable 对象,如下所示。当我 post 执行单个 EventInputDto
且格式不正确的 Url
属性 的操作时,我的验证成功进行。当我 post 到 EventInputDto
的集合时,它不起作用并且没有验证。
如果我使用常规 MVC 属性(即必需/电子邮件),它们将与集合以及单个对象一起使用。我如何让它与 FluentValidation 一起使用?我没有使用内部集合,所以我不确定为什么它不能按预期工作。
public async Task<IActionResult> CreateEventCollection([FromBody] IEnumerable<EventInputDto> events)
{
if (!ModelState.IsValid)
{
return UnprocessableEntity(ModelState); //does not work
}
}
我的验证器是使用泛型设置的,因为我使用单独的模型进行输入和更新。
public class EventManipulationValidator<T> : AbstractValidator<T> where T : EventManipulationDto
{
public EventManipulationValidator()
{
RuleFor(manipulationDto => manipulationDto.Title).NotNull().WithMessage("Title cannot be blank")
.Length(1, 50);
RuleFor(manipulationDto => manipulationDto.Message).NotNull().WithMessage("Message cannot be blank")
.Length(1, 1000);
RuleFor(manipulationDto => manipulationDto.ScheduledTime).NotNull().WithMessage("Scheduled Time cannot be blank");
RuleFor(inputDto => inputDto.Url).Matches(@"https://.*windows\.net.*").WithMessage("The url must be valid and stored on Azure");
}
}
由于我的 CreateEventCollection 操作接受了 EventInputDto 的 IEnumerable,因此我的 EventInputDto 验证器设置如下:
public class EventInputValidator : EventManipulationValidator<EventInputDto>
{
public EventInputValidator()
{
//all property validators are inherited from EventManipulationValidator
}
}
public class EventInputCollectionValidator : AbstractValidator<IEnumerable<EventInputDto>>
{
public EventInputCollectionValidator()
{
RuleForEach(p => p).SetValidator(new EventManipulationValidator<EventInputDto>());
}
}
以下是我的模型供参考:
EventManipulationDto
public abstract class EventManipulationDto
{
public string Title { get; set; }
public string Message { get; set; }
public string Url { get; set; }
public DateTime? ScheduledTime { get; set; }
}
EventInputDto
public class EventInputDto : EventManipulationDto
{
//all properties inherited from base class
}
在查看了项目 GitHub 的 open/closed 个问题列表后,似乎我的方法并非全部都是必需的。不需要我的 EventInputCollectionValidator。 FluentValidation 不再需要像我上面定义的那样显式定义 IEnumerable 验证器。
定义一个基本的 AbstractValidator 就足够了,或者在我的例子中是一个从父 class 继承的验证器。
唯一需要让它工作的改变是在我的 startup.cs 注册 fluentvalidation 时。我需要明确添加 ImplicitlyValidateChildProperties = true
。没有意识到这是必需的,因为我认为这是为了验证子 属性 集合而不是父集合对象。现在完美运行。
.AddFluentValidation(fv => {
fv.RunDefaultMvcValidationAfterFluentValidationExecutes = true;
fv.RegisterValidatorsFromAssemblyContaining<Startup>();
fv.ImplicitlyValidateChildProperties = true;
});