An ASP.NET MVC validator to make sure at least one checkbox is checked

爷,独闯天下 提交于 2019-11-27 18:22:48

问题


I have an ASP.NET MVC 2 project in which I've created a data transfer object to receive data from a web page form. The form has two groups of checkboxes on it. I want to validate the object to make sure that at least one of the checkboxes in each group is checked.

I'm doing the validation on the server side so that a user won't be able to hack around any client-side validation. (I will add client-side validation with jQuery later; that's easy.)

My understanding is that I have to create my own custom ValidationAttribute for my data transfer object class, but I don't understand how to create and use one that can accept an arbitrary list of checkbox properties to make sure that at least one of them is true. I am guessing I will have to call the attributes like this:

[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
{
    ...
}

What would the implementation of AtLeastOneCheckboxAttribute look like?

Or is there a different way that I should do this kind of validation?


回答1:


if you have several checkbox groups, you just need to deine the attribute several times.

[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);
        }
    }
}

UPDATE

as you have found out, class-level validation is called only after all properties pass. In order to get the error, just use empty string as the key.




回答2:


Your DTO, which is I'm guessing your ViewModel can ihert IDataErrorInfo. Then you can do your validation like this (note I didn't compile this)

//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; } }
}


来源:https://stackoverflow.com/questions/4491521/an-asp-net-mvc-validator-to-make-sure-at-least-one-checkbox-is-checked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!