Reputation: 1518
Using FluentValidation I typically pass Ids vs the objects in Commands. Yet I want to validate that an object with the id exists, and then validate that object.
Is there a better way than the below method?
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());
});
}
}
Upvotes: 1
Views: 2634
Reputation: 47375
What about something like this?
public class UpdateProjectCommandValidator : AbstractValidator<UpdateProjectCommand>
{
public UpdateProjectCommandValidator(DbContext dbContext) {
RuleFor(x => x.Id)
.MustFindProjectById(dbContext);
}
}
Then your MustFindProjectById
extension method would look something like this:
public static class MustFindProjectByIdExtensions {
public static IRuleBuilderOptions<T, int> MustFindProjectById<T>
(this IRuleBuilder<T, int> ruleBuilder, DbContext dbContext) {
return ruleBuilder.SetValidator(new MustFindProjectById(dbContext));
}
}
...and it is just a wrapper around a custom 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;
}
}
Upvotes: 1
Reputation: 1518
After some research I think this is a better way.
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;
}));
Upvotes: 0