“自定义验证”中的“对象引用未设置为对象的实例”

时间:2017-01-11 10:23:19

标签: c# asp.net asp.net-mvc razor

我正在尝试创建一个自定义验证规则,在任何情况下检查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我只是渲染现有项目。我不确定这是什么原因以及我是否正确进行验证。

1 个答案:

答案 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引用。