FluentValidation 按 id 验证对象

本文关键字:对象 验证 id FluentValidation | 更新日期: 2023-09-27 18:34:10

使用 FluentValidation 我通常会传递 Ids 和 Commands 中的对象。 但是,我想验证具有 id 的对象是否存在,然后验证该对象。

有没有比以下方法更好的方法?

    public class ProjectIdValidator : AbstractValidator<int>
    {
        public ProjectIdValidator(MyDbContext aDbContext)
        {
            Custom(aProjectId =>
            {
                var project = aDbContext.Projects.Find(aProjectId);
                if (project == null)
                {
                    return new ValidationFailure("ProjectId", "Project does not exist");
                }
                var projectValidator = new ProjectValidator();
                var x = projectValidator.Validate(project);
                if (x.IsValid)
                {
                    return null;
                }
                return new ValidationFailure("ProjectId", x.Errors.ToString());
            });
        }
    }

FluentValidation 按 id 验证对象

这样的事情呢?

public class UpdateProjectCommandValidator : AbstractValidator<UpdateProjectCommand>
{
    public UpdateProjectCommandValidator(DbContext dbContext) {
        RuleFor(x => x.Id)
            .MustFindProjectById(dbContext);
    }
}

然后,您的MustFindProjectById扩展方法将如下所示:

public static class MustFindProjectByIdExtensions {
    public static IRuleBuilderOptions<T, int> MustFindProjectById<T>
        (this IRuleBuilder<T, int> ruleBuilder, DbContext dbContext) {
        return ruleBuilder.SetValidator(new MustFindProjectById(dbContext));
    }
}

。它只是一个自定义PropertyValidator的包装器:

internal class MustFindProjectById : PropertyValidator {
    private readonly DbContext _dbContext;
    internal MustFindProjectById(DbContext dbContext) {
        _dbContext = dbContext;
    }
    protected override IsValid(PropertyValidatorContext) {
        var projectId = (int)context.PropertyValue;
        var entity = dbContext.Projects.Find(projectId);
        return entity != null;
    }
}

经过一些研究,我认为这是一个更好的方法。

AddRule(new DelegateValidator<Command>((aCommand, aContext) =>
{
    // return an IEnumerable<ValidationFailure> from in here:
    var projectId = (int?) aCommand.ProjectId;
    if (projectId.HasValue)
    {
        using (var dbContextScope = aDbContextScopeFactory.CreateReadOnly())
        {
            MyDbContext dbContext = dbContextScope.DbContexts.Get<MyDbContext>();
            Project project = dbContext.Projects.Find(projectId);
            if (project == null)
            {
                return Enumerable.Repeat(new ValidationFailure("ProjectId", "ProjectId not found"),1);
            }
            var projectValidator = new ProjectValidator();
            var results = projectValidator.Validate(project);
            return results.Errors;
        }
    }
    return null;
}));