DataAnnotation и необязательные значения DateTime - PullRequest
4 голосов
/ 05 августа 2011

Я работаю с HTML-формой, которая принимает 4 даты, две из которых являются необязательными.Эти даты вставляются в базу данных 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, и я получаю сообщение об ошибке проверки:

Не удалось преобразовать значение типа 'null' в 'System.DateTime', как ожидалось методом GoalManager.Models..Goal.ValidateGoalDate.Необходимо ввести действительную дату.

Шагая по коду, я вижу, что пользовательский валидатор не запускается в необязательных полях, но когда я удаляю DataAnnotation из этих необязательных полей, я не возвращаю ошибку.Если пользователь не вставляет дату в поле, я хочу вставить NULL в таблицу. Как сообщить Валидатору, что я не хочу проверять ошибку на пустую (или нулевую) дату, игнорировать ее и вставлять нулевую в базу данных?

Ответы [ 3 ]

5 голосов
/ 05 августа 2011

DateTime, который ваш пользовательский валидатор использует в качестве параметра, в вашем примере не обнуляется ... Если вы сделаете его датируемым, то это должно решить вашу проблему.

2 голосов
/ 05 августа 2011

Вот реализация того, что сказал @Rikon:

public static ValidationResult ValidateGoalDate(DateTime? goalDate) {
0 голосов
/ 22 марта 2012

Это (вероятно) позволит избежать исключения, но я полагаю, что вам нужно добавить больше кода внутри метода:

public static ValidationResult ValidateGoalDate(DateTime goalDate = new DateTime())

Если у вас все еще есть проблема с возвращением false ModelState.IsValid,вы можете поместить что-то вроде этого в контроллер:

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

...