ASP MVC对复杂属性进行了非常有效的验证

时间:2013-08-22 10:26:24

标签: c# .net asp.net-mvc validation unobtrusive-validation

我有下一个(简化的)视图模型:

    public class RegisterModel
{
    public string UserName { get; set; }

    [MustExistIf("SomeProperty", "some value", "SomeOtherProperty", ErrorMessage = "You have to select something")]
    public string LastName { get; set; }

    public AddressModel Address { get; set; }

}

    public class AddressModel
{
    public string Street { get; set; }

    public string House { get; set; }
}

我有自定义验证器

    public class MustExistIfAttribute : ValidationAttribute, IClientValidatable
{
    private string _masterName { get; set; }

    private object _masterValue { get; set; }

    private string _dependantName { get; set; }

    public MustExistIfAttribute(string masterName, object masterValue, string dependantName)
    {
        this._masterName = masterName;
        this._masterValue = masterValue;
        this._dependantName = dependantName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // get value of master property
        var masValue = _getValue(validationContext.ObjectInstance, _masterName);

        // get value of property whch depends on master property
        var depValue = _getValue(validationContext.ObjectInstance, _dependantName);

        if (masValue.Equals(_masterValue)) // if value in request is equal to value in specified in data annotation
        {
            if (depValue == null) // if dependant value does not exist
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }

        return ValidationResult.Success;
    }

    public override bool IsValid(object value)
    {
        return base.IsValid(value);
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var modelClientValidationRule = new ModelClientValidationRule
        {
            ValidationType = "mustexistif",
            ErrorMessage = FormatErrorMessage(metadata.DisplayName)
        };
        modelClientValidationRule.ValidationParameters.Add("mastername", this._masterName);
        modelClientValidationRule.ValidationParameters.Add("mastervalue", this._masterValue);
        modelClientValidationRule.ValidationParameters.Add("dependantname", this._dependantName);
        yield return modelClientValidationRule;
    }

    private static object _getValue(object objectInstance, string propertyName)
    {
...
    }
}

我有下一个javascript(请忽略在mustexitif方法中返回false - 它仅用于测试目的)

(function () {

    jQuery.validator.addMethod('mustexistif', function (value, element, params) {
        var masterName = params['mastername'];
        var masterValue = params['mastervalue'];
        var dependantName = params['dependantname'];
        return false;
    });


    var setValidationValues = function (options, ruleName, value) {
        options.rules[ruleName] = value;
        if (options.message) {
            options.messages[ruleName] = options.message;
        }
    };
    var $Unob = $.validator.unobtrusive;

    $Unob.adapters.add("mustexistif", ["mastername", "mastervalue", "dependantname"], function (options) {
        var value = {
            mastername: options.params.mastername,
            mastervalue: options.params.mastervalue,
            dependantname: options.params.dependantname
        };
        setValidationValues(options, "mustexistif", value);
    });
})();

当我使用MustExistIf注​​释装饰RegisterModel类的LastName属性时,它按预期工作(如提供的代码中所示)。 但我真正想要的是使用MustExistIf注​​释装饰RegisterModel的复杂Address属性。问题是,当我这样做时,没有任何unobrusive适配器被注册(javascript正在执行那不被触发)。 因此,当我对简单和复杂属性进行decore时,存在差异。我的解决方案不允许我装饰Address类的属性(FYI,我尝试过,然后验证工作正常)。有没有办法实现我的意图?我错过了什么吗? Woud解决方案是在模型级别进行验证吗?但是可以进行客户端验证吗?

1 个答案:

答案 0 :(得分:0)