Validating a property if another property has a value on MVC 3/jQuery Validator

前端 未结 3 1375
心在旅途
心在旅途 2021-01-06 03:11

how can I use a Required Validation in a property Prop2 only if the Prop1 is true?

Ex:
public bool Prop1 { get; set; }

[Required] // I need this validation          


        
3条回答
  •  隐瞒了意图╮
    2021-01-06 03:54

    There are two parts to this. First, you have to write a required attribute that's only required if the other property meets your criteria.

    You'd have to do something like:

    public class RequiredComparerAttribute : RequiredAttribute
    {
        public OtherProperty { get; set; }
        public override bool IsValid(object value)
        {
            // TODO: use reflection to validate other property as PropertyInfo 
            // or validate it's value after it is decided to be valid
    
            foreach (ValidationAttribute va in property
                .GetCustomAttributes(typeof(ValidationAttribute), true)
                .OfType())
            {
                if (!va.IsValid(value))
                {
                    return false; // not required
                }
            }
            return  true; // required
        }
    }
    

    Then, in Application_Start in the Global.asax, you'll have to register the validator, which you can just reuse the RequiredAttribute's validator:

            DataAnnotationsModelValidatorProvider
                .RegisterAdapter(typeof(RequiredComparerAttribute),
                  typeof(RequiredAttributeAdapter));
    

    If you want to add your own validator, you'll have to write a custom validator. Phil Haack has an example on his blog: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

    Edit: Take a look at CompareAttribute in .NET Reflector for a sense of how to get the value of the OtherProperty. CompareAttribute also implements IClientValidatable to provide those validation rules needed on the client side.

    I don't think CompareAttribute will work for you because you have to validate that a value is required based on content of another property, not compare the equality of two properties.

    Edit2: What does the Validation provider do?

    It adds rules to the form and provides messages for those rules. You can see exactly how the RequiredAttributeAdapter does this by downloading the MVC 3 source. To understand what it does on the client side, you can open the MVC 3 page in Google Chrome, hit CTRL+SHIFT+J to bring up a developer tools window and enter:

    $('form:first').data().unobtrusiveValidation.options
    

    The rules object inside options specifies how to validate each item and the message object specifies the error message that will be displayed for each validation error.

    Edit3: Full example

    Since answering this question, I've written a blog post with a full example of creating a custom attribute on the client (unobtrusive validation) and server. The blog post is here. This example is for a 'contains' attribute, but it should be pretty easy to modify to become a required comparison.

提交回复
热议问题