0

i am using asp.net MVC 3 , in my module there are two types of payment modes 1. Wire transfer and 2. PayPal . Now depending on this type 1 and 2 the properties are to be kept Required or other data annotations ! how to do this ? for eg :

There is a Radio button for payment type ,

If type 1- i.e Wire Transfer is selected then these fields should be validated - First name , last name , email,beneficiary name , bank name , bank no , ifsc code etc if it is type 2- i.e PayPal then these fields are required - PayPal email .

This could be done by manual validation but is there some way to do it the right way with DataAnnotations?

4 Answers 4

4

Simon Ince's blog post seems to be outdated.

There is no need to use DataAnnotationsModelValidator or do a DataAnnotationsModelValidator registration.

You can use the following code:

[AttributeUsage(AttributeTargets.Property, AllowMultiple=false)]
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable {
    private const string _defaultErrorMessage = "'{0}' is required when {1} equals {2}.";

    public string DependentProperty { get; set; }
    public object TargetValue { get; set; }

    public RequiredIfAttribute(string dependentProperty, object targetValue):base(_defaultErrorMessage) {
        this.DependentProperty = dependentProperty;
        this.TargetValue = targetValue;
    }
    public override string FormatErrorMessage(string name) {
        return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, DependentProperty, TargetValue);
    }
    protected override ValidationResult IsValid(object value, ValidationContext context) {
        if (context.ObjectInstance != null) {
            Type type = context.ObjectInstance.GetType();
            PropertyInfo info = type.GetProperty(DependentProperty);
            object dependentValue;
            if (info != null) {
                dependentValue = info.GetValue(context.ObjectInstance, null);
                if (object.Equals(dependentValue, TargetValue)) {
                    if (string.IsNullOrWhiteSpace(Convert.ToString(value))) {
                        return new ValidationResult(ErrorMessage);
                    }
                }
            }
        }
        return ValidationResult.Success;
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
        ModelClientValidationRule rule = new ModelClientValidationRule();
        rule.ErrorMessage = this.FormatErrorMessage(metadata.PropertyName);
        rule.ValidationType = "requiredif";
        rule.ValidationParameters.Add("depedentproperty", DependentProperty);
        rule.ValidationParameters.Add("targetvalue", TargetValue);
        yield return rule;
    }
}

and the javascript side: if you are using jquery:

    $.validator.unobtrusive.adapters.add('requiredif', ['depedentproperty', 'targetvalue'], function (options) {
    options.rules["required"] = function (element) {
        return $('#' + options.params.depedentproperty).val() == options.params.targetvalue
    };
    if (options.message) {
        options.messages["required"] = options.message;
    }
    $('#' + options.params.depedentproperty).blur(function () {
        $('#' + options.element.name).valid();
    });
});
Sign up to request clarification or add additional context in comments.

Comments

3

I've updated my example to use MVC 3, so that one is more up to date.

http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx

Comments

1

You could write a custom validator attribute and decorate your model with it:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class CustomValidationAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        var model = value as MyViewModel;
        if (model == null)
        {
            return false;
        }
        if (model.WireTransfer == 1)
        {
            return !string.IsNullOrEmpty(model.FirstName) &&
                   !string.IsNullOrEmpty(model.LastName);
        }
        else if (model.WireTransfer == 2)
        {
            return !string.IsNullOrEmpty(model.PaypalEmail);
        }
        return false;
    }
}

and then in your main Model:

[CustomValidation]
public class MyViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    ...
}

5 Comments

thnx !! but the problem is that in this case the client side validation wont be working ?
@bhuvin, no, it won't be working, but you could make it work by implementing IClientValidatable: devtrends.co.uk/blog/…
@darin have tried it with other things but still it isnt working
@bhuvin, not working is not enough. What exactly have you tried? What exactly didn't work? The blog post I've linked in my previous comment is more than clear and it illustrates a working example. There is also Part 1 that you might read.
Thnx Darin !! Thank you very much !!
0

I have used the approach from Simon Ince's blog post and it works well. Basically he creates a RequiredIf data attribute where you can specify the other property and value that must be true in order to make the current field required.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.