帮助mvc条件模型验证

时间:2011-03-23 05:32:59

标签: c# asp.net-mvc asp.net-mvc-3

我正在使用asp.net MVC 3,在我的模块中有两种类型的支付模式1.电汇和2.PayPal。现在,根据此类型1和2,属性将被保留为必需或其他数据注释!这该怎么做 ? 例如:

付款类型有一个单选按钮,

如果选择类型1-即电汇,则应验证这些字段 - 名字,姓氏,电子邮件,受益人姓名,银行名称,银行号,ifsc代码等 如果是2型,即PayPal,则需要这些字段 - PayPal电子邮件。

这可以通过手动验证来完成,但是有一些方法可以通过DataAnnotations以正确的方式完成吗?

4 个答案:

答案 0 :(得分:4)

Simon Ince的博客文章似乎已经过时了。

无需使用DataAnnotationsModelValidator或执行DataAnnotationsModelValidator注册。

您可以使用以下代码:

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

和javascript方面:如果你使用的是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();
    });
});

答案 1 :(得分:3)

我已经更新了我的示例以使用MVC 3,因此一个更新。

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

答案 2 :(得分:1)

您可以编写自定义验证器属性并使用它来装饰您的模型:

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

然后在你的主模型中:

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

答案 3 :(得分:0)

我使用了Simon Ince's blog post的方法,效果很好。基本上,他创建了一个RequiredIf数据属性,您可以在其中指定必须为true的其他属性和值,以便使当前字段成为必需。