Валидатор ASP.NET MVC, чтобы убедиться, что установлен хотя бы один флажок - PullRequest
6 голосов
/ 20 декабря 2010

У меня есть проект ASP.NET MVC 2, в котором я создал объект передачи данных для получения данных из формы веб-страницы.Форма имеет две группы флажков.Я хочу проверить объект, чтобы убедиться, что хотя бы один из флажков в каждой группе отмечен.

Я делаю проверку на стороне сервера, чтобы пользователь не смог взломатьлюбая проверка на стороне клиента.(Я добавлю проверку на стороне клиента с помощью jQuery позже; это просто.)

Насколько я понимаю, мне нужно создать собственный настраиваемый атрибут ValidationAttribute для моего класса объекта передачи данных, но я не понимаю, как его создатьи использовать тот, который может принять произвольный список свойств флажка, чтобы убедиться, что хотя бы одно из них является истинным.Я предполагаю, что мне придется вызывать атрибуты следующим образом:

[AtLeastOneCheckbox("set1check1", "set1check2", "set1check3",
    ErrorMessage = "You must check at least one checkbox in set 1.")]
[AtLeastOneCheckbox("set2check1", "set2check2", "set2check3", "set2check4", "set2check5",
    ErrorMessage = "You must check at least one checkbox in set 2.")]
public class MyFormDTO
{
    ...
}

Как будет выглядеть реализация AtLeastOneCheckboxAttribute?

Или есть другой способ, которым я должен сделать такойпроверка

Ответы [ 2 ]

5 голосов
/ 20 декабря 2010

если у вас есть несколько групп флажков, вам просто нужно определить атрибут несколько раз.

[AttributeUsage( AttributeTargets.Class)]
public class AtLeastOneCheckboxAttribute : ValidationAttribute
{
    private string[] _checkboxNames;

    public AtLeastOneCheckboxAttribute(params string[] checkboxNames)
    {
        _checkboxNames = checkboxNames;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var propertyInfos = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(x=>_checkboxNames.Contains(x.Name));

        var values = propertyInfos.Select(x => x.GetGetMethod().Invoke(value, null));
        if (values.Any(x => Convert.ToBoolean(x)))
            return ValidationResult.Success;
        else
        {
            ErrorMessage = "At least one checkbox must be selected";
            return new ValidationResult(ErrorMessage);
        }
    }
}

ОБНОВЛЕНИЕ

как вы выяснили, проверка на уровне класса вызывается только после того, как все свойства пройдены.Чтобы получить ошибку, просто используйте пустую строку в качестве ключа .

0 голосов
/ 20 декабря 2010

Ваш DTO, который, я думаю, ваша ViewModel может ihert IDataErrorInfo.Затем вы можете выполнить проверку таким образом (заметьте, я не компилировал это)

//I'm guessing you have a list of checkboxes
IEnumerable<bool> checkBoxes1;
IEnumerable<bool> checkBoxes2;

public class MyFormDTO : IDataErrorInfo
{
    public string this[string prop]
    {
        get
        {
            if(prop == "checkBoxes1")
            {
                if(checkBoxes1.Any(x => x == true))
                {
                    return "Error: You need to select atleast one checkbox from set1";
                }
            }
            else if(prop == "checkBoxes2")
            {
                if(checkBoxes2.Any(x => x == true))
                {
                    return "Error: You need to select atleast one checkbox from set2";
                }
            }
            return null;
        }
    }
    public string Error { get { return null; } }
}
...