FluentValidation 通过 id 验证对象
FluentValidation Validate object by id
我通常使用 FluentValidation 传递 ID 与命令中的对象。但是我想验证一个带有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());
});
}
}
经过一番研究,我认为这是一种更好的方法。
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;
}));
这样的事情怎么样?
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;
}
}
我通常使用 FluentValidation 传递 ID 与命令中的对象。但是我想验证一个带有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());
});
}
}
经过一番研究,我认为这是一种更好的方法。
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;
}));
这样的事情怎么样?
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;
}
}