我正在使用一个接受4个日期的HTML表单,其中两个是可选的。这些日期被插入到MS SQL数据库中,因此我正在边界检查从表单传递的DateTime变量,对SqlDateTime.MinValue
和SqlDateTime.MaxValue
进行检查。这是我的模型的样子:
[Required]
[DisplayName("Planned Start Date")]
[CustomValidation(typeof(Goal), "ValidateGoalDate")]
public object planned_start_date { get; set; }
[DisplayName("Actual Start Date")]
[CustomValidation(typeof(Goal), "ValidateGoalDate")]
public object start_date { get; set; }
[Required]
[DisplayName("Planned End Date")]
[CustomValidation(typeof(Goal), "ValidateGoalDate")]
public object planned_end_date { get; set; }
[DisplayName("Actual Start Date")]
//[CustomValidation(typeof(Goal), "ValidateGoalDate")]
public object end_date { get; set; }
我的自定义验证器:
public static ValidationResult ValidateGoalDate(DateTime goalDate) {
//* this does not appear to work ever because the optional field does
//* not ever get validated.
if (goalDate == null || goalDate.Date == null)
return ValidationResult.Success;
if (goalDate.Date < (DateTime)SqlDateTime.MinValue)
return new ValidationResult("Date must be after " + SqlDateTime.MinValue.Value.ToShortDateString());
if (goalDate.Date > (DateTime)SqlDateTime.MaxValue)
return new ValidationResult("Date must be before " + SqlDateTime.MaxValue.Value.ToShortDateString() );
return ValidationResult.Success;
}
每当您提交没有可选值的表单时,就会出现问题。在我的控制器中,我的ModelState.IsValid返回false,我收到验证错误消息:
无法通过方法GoalManager.Models.Goal.ValidateGoalDate将“null”类型的值转换为“System.DateTime”。必须输入有效日期。
单步执行代码,我发现自定义验证器不会在可选字段上运行,但是当我从这些可选字段中删除DataAnnotation时,我没有返回任何错误。如果用户没有在字段中插入日期,我想在表中插入NULL。 如何告诉Validator我不想错误检查空白(或空)日期,忽略它,并将空值插入数据库?
答案 0 :(得分:5)
您的自定义验证程序作为参数使用的DateTime在您的示例中不可为空...如果您使其成为可以为空的DateTime,它应该可以解决您的问题。
答案 1 :(得分:2)
以下是@Rikon所说的实现:
public static ValidationResult ValidateGoalDate(DateTime? goalDate) {
答案 2 :(得分:0)
这将(可能)避免异常,但我想你必须在方法中使用更多代码来跟进它:
public static ValidationResult ValidateGoalDate(DateTime goalDate = new DateTime())
如果ModelState.IsValid返回false仍有问题,可以在控制器中输入这样的内容:
foreach (var state in ModelState) {
if (state.Key == "start_date") state.Value.Errors.Clear();
}
(我确信有更好的方法可以做到这一点,但没关系,至少这是不言自明的)
顺便说一下,完全禁用验证是不明智的,因为它会启用注入安全漏洞。有关验证的更多信息,以及如何在客户端基于每个字段禁用它,请阅读:http://msdn.microsoft.com/en-us/library/aa479045.aspx#aspplusvalid%5Fclientside