我正在尝试创建一个自定义验证规则,在任何情况下检查Times是否重叠,为此我有以下内容:
public class TimesheetLogicAttribute : ValidationAttribute
{
public TimesheetLogicAttribute()
{
//this.jobRecords = jobRecords;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var records = value as List<TimesheetJobRec>;
records = records.OrderBy(r => r.StartTime).ToList();
DateTime? current = null;
foreach(var record in records)
{
if (record.StartTime > record.FinishTime)
{
return new ValidationResult("Finish time is before start time on " + record?.JobNumber);
}
if (current == null)
{
current = record.FinishTime;
continue;
}
if(record.StartTime < current)
{
return new ValidationResult("Time overlapping");
}
current = record.FinishTime;
}
return ValidationResult.Success;
//return base.IsValid(value, validationContext);
}
}
我的相应模型是:
public class TimesheetJobRec : ModelsBase
{
// Job number stuff needs to go in here.
[Required]
public string JobNumber { get; set; }
public Timesheet Timesheet { get; set; }
[Required]
public string WorkDescription { get; set; }
[Required]
[DataType(DataType.Time)]
public DateTime StartTime { get; set; }
[Required]
[DataType(DataType.Time)]
public DateTime FinishTime { get; set; }
[Required]
public double LunchTime { get; set; }
[ReadOnly(true)]
[Range(0.25, 24)]
public double Total { get; set; }
}
然后我装饰我的视图模型:
[Display(Name = "Job Records")]
[TimesheetLogic]
public IList<TimesheetJobRec> JobRecords { get; set; }
一切正常,在我的验证中,我正确地收到了项目列表,返回ValidationResult
时出现问题我在ASP方面遇到以下错误:
对象引用未设置为对象的实例。
Line 43: <th>Total</th>
Line 44: </tr>
Line 45: @foreach (var item in Model.JobRecords)
Line 46: {
Line 47: Html.RenderPartial("_JobEditorRow", item);
在第45行上引发错误,在我的视图中foreach
我只是渲染现有项目。我不确定这是什么原因以及我是否正确进行验证。
答案 0 :(得分:1)
您必须将传递给视图的视图模型的每个实例的JobRecords属性设置为IList<TimesheetJobRec>
。您可以使用自动属性初始值设定项在C#6中初始化属性:
[Display(Name = "Job Records")]
[TimesheetLogic]
public IList<TimesheetJobRec> JobRecords { get; set; } = new List<TimesheetJobRec>();
或者您可以在视图模型类
的构造函数中执行此操作//constructor
public YourViewModel()
{
JobRecords = new List<TimesheetJobRec>();
}
这将确保始终初始化该属性,前提是您未在某处明确将其设置为null
引用。