【发布时间】:2019-05-21 19:20:37
【问题描述】:
假设我有 2 个视图模型,项目和任务。该项目包含一个任务列表。该项目有一个 BeginDate 和一个 EndDate。每个任务也都有一个 BeginDate 和一个 EndDate。
项目类
public class Project
{
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
public List<Task> Tasks { get; set; }
}
任务类
public class Task
{
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
}
我想使用 FluentValidation 来验证任务中的每个日期是否在项目的日期范围内。我可以这样做:
ProjectValidator 类
public class ProjectValidator : AbstractValidator<Project>
{
public ProjectValidator()
{
RuleForEach(x => x.Tasks)
.Must(((p, t) => t.BeginDate >= p.BeginDate && t.BeginDate <= p.EndDate))
.WithMessage("Task Begin Date must be within Project's Begin and End Dates.");
RuleForEach(x => x.Tasks)
.Must(((p, t) => t.EndDate >= p.BeginDate && t.EndDate <= p.EndDate))
.WithMessage("Task End Date must be within Project's Begin and End Dates.");
}
}
但是,这不会标记存在问题的特定任务开始或结束日期。错误消息显示在错误摘要的屏幕顶部,而不是问题日期旁边。要检查的日期可能有十几个或更多,因此很难确定哪个日期确实是问题所在。
这大概是因为我在项目级别而不是单个任务级别进行验证。要获取带有错误消息标记的任务中的字段,我需要验证任务。
所以我需要写一个TaskValidator,像这样:
TaskValidator 类
public class TaskValidator : AbstractValidator<Task>
{
Project _proj;
public TaskValidator(Project proj)
{
_proj = proj;
RuleFor(x => x.BeginDate)
.Must(BeWithinProjectDates)
.WithMessage("Task Begin Date must be within Project's Begin and End Dates.");
RuleFor(x => x.EndDate)
.Must(BeWithinProjectDates)
.WithMessage("Task End Date must be within Project's Begin and End Dates.");
}
private bool BeWithinProjectDates(DateTime date)
{
return (date >= _proj.BeginDate &&
date <= _proj.EndDate);
}
}
然后我可以在规则中将项目视图模型传递给 TaskValidator,如下所示:
ProjectValidator 类(修改)
public class ProjectValidator : AbstractValidator<Project>
{
public ProjectValidator()
{
RuleForEach(x => x.Tasks)
.SetValidator(x => new TaskValidator(x));
}
}
不幸的是,这不起作用。 TaskValidator 构造函数被调用一次,以初始化验证器。在验证发生时不会调用它。这意味着 Project 对象是空的。
有什么方法可以从 TaskValidator 中引用项目视图模型,以便我可以访问项目开始日期和结束日期的值?
【问题讨论】:
标签: c# validation fluentvalidation