FluentValidation对外部模型对象的收集不起作用

时间:2018-11-10 05:33:12

标签: c# asp.net asp.net-mvc fluentvalidation

我无法让FluentValidation处理一组对象。我的控制器POST操作采用IEnumerable对象,如下所示。当我发布一个采用单个EventInputDto且格式错误的Url属性的操作时,我的验证成功完成。当我发布到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
   }

1 个答案:

答案 0 :(得分:1)

浏览完项目GitHub上未解决/未解决问题的列表后,似乎并不需要我所有的方法。不需要我的EventInputCollectionValidator。 FluentValidation不再需要像我上面定义的那样显式定义IE​​numerable验证器。

定义基本AbstractValidator或从父类继承的验证器就足够了。

注册fluentvalidation时,使其生效所需的唯一更改是在startup.cs中。我需要显式添加ImplicitlyValidateChildProperties = true。没意识到这是必需的,因为我认为这是为了验证子属性集合而不是父集合对象。现在可以正常工作。

.AddFluentValidation(fv => {
                    fv.RunDefaultMvcValidationAfterFluentValidationExecutes = true;
                    fv.RegisterValidatorsFromAssemblyContaining<Startup>();
                    fv.ImplicitlyValidateChildProperties = true;
                });