Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
788 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...