Палец вверх 0
Перевод
Перевод

Настраиваемый атрибут проверки MVC 3 для нескольких флажков

Я делаю проверку на длинную форму, используя пользовательский атрибут. Одним из входящих полей является длинная серия флажков, которые я использую, чтобы позволить пользователям устанавливать несколько значений для соответствующего поля базы данных (я знаю, что мог бы использовать MultiSelectList, но я не большой поклонник их). Затем я собираю различные значения флажков в методе POST ActionResult в одну строку перед загрузкой в базу данных. Эта часть работает хорошо.

Но мне нужно проверить, что они отметили хотя бы один флажок (т.е. само значение базы данных не может быть нулевым). Поэтому я написал собственный атрибут проверки, который проверяет наличие каждого флажка, и, если хотя бы один из них присутствует, он проходит проверку. Вот код, который я написал для самой проверки:

public class ConfirmLAAttribute : ValidationAttribute
{
    public ConfirmLAAttribute()
    {
    }

    protected override ValidationResult IsValid(Object value, ValidationContext validationContext)
    {
        string lAppTest = String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAAccent") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAShade") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAArticulation") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAMassing") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAScreening") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LARock") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAEdging") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAWindbreak") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAGroundcover") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LANaturalizing") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAOrchard") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LATopiary") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAHerb") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LAContainer") != null) ? "X" : String.Empty;
        lAppTest += (validationContext.ObjectType.GetProperty("LABog") != null) ? "X" : String.Empty;

        if (String.IsNullOrEmpty(lAppTest)) {
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
        return ValidationResult.Success;
    }
}

Я вызываю проверку в качестве атрибута модели представления:

[ConfirmLA(ErrorMessage = "You must select at least one Landscape Application!")]
public string Landscape_Application { get; set; }

HTML-код в модели представления просто повторяет:

<input type="checkbox" name="LAAccent" value="true" /> Accent/Feature<br />

внутри таблицы (т.е. это 15 раз, по одному на каждый флажок).

Проблема в том, что это всегда выдает ошибку. Я отлаживал внутри самого кода проверки, и он не распознает ни один из флажков по именам их свойств. Другими словами, каждый из них:

lAppTest += (validationContext.ObjectType.GetProperty("LAAccent") != null) ? "X" : String.Empty;

разрешается в ноль, даже если флажок был установлен. Я также подтвердил, что проверенные значения обязательно присутствуют в FormCollection в ActionResult. Как будто у меня неправильный синтаксис или что-то в этом роде, например, метод GetProperty не находит эти флажки по именам их свойств. Что я здесь не так делаю?

validation forms asp.net-mvc-3 custom-attributes
задан Sylver 29 февр. 2012 г., 4:06:59
источник

2 ответа

Решение 4
Перевод
Перевод

Измените модель просмотра на

[Required(ErrorMessage = "You must select at least one Landscape Application!")]
public ICollection<string> LandscapeServices { get; set; }

Измените свой HTML, чтобы быть

<input type="checkbox" class="required-checkbox" name="LandscapeServices" value="LAAccent" /> Accent/Feature<br />
<input type="checkbox" class="required-checkbox" name="LandscapeServices" value="LAShade" /> Accent/Feature<br />
<input type="checkbox" class="required-checkbox" name="LandscapeServices" value="LAArticulation" /> Accent/Feature<br />
/*etc etc*/

При нажатии кнопки «Отправить» все выбранные значения будут добавлены в свойство LandscapeServices.

Обратите внимание, что это будет работать только для проверки на стороне сервера. Если вам нужна проверка на стороне клиента, вам нужно создать расширение для Required с вашей собственной функцией проверки JavaScript.

РЕДАКТИРОВАТЬ - направить @ ScubaSteve комментарий о проверке на стороне клиента из SO ответа

$(function(){
    $.validator.addMethod('required_group', function(value, element) {
        var $module = $(element).parents('form');
        return $module.find('input.checkbox:checked').length;
    }, 'Select at least one Service please');
    $.validator.addClassRules('required-checkbox', { 'required_group' : true });
ответ дан heads5150 29 февр. 2012 г., 5:55:31
источник
Палец вверх 0
Перевод
Перевод

Я бы не использовал для этого атрибут, если только вы не хотите выполнять проверку на стороне клиента. Вместо этого я просто сделал бы вашу модель производной от IValidatableObject и выполнил валидацию в методе IsValid этого. Гораздо проще и без позднего связывания.

ответ дан Erik Funkenbusch 29 февр. 2012 г., 5:24:30
источник