MVC通过客户端删除自定义验证规则

时间:2015-10-27 18:53:43

标签: javascript jquery asp.net-mvc forms validation

这是我的情景。我有一个表单,用户可以提交工作单。我正在使用模型数据。在我的模型中,我有3个具有数据注释的属性,如下所示

    [Required(ErrorMessage="Please enter a start date.")]
    [DataType(DataType.DateTime)]
    [Display(Name = "Start Date")]
    public Nullable<DateTime> DateWorkStarted { get; set; }

    [Required(ErrorMessage="Please enter a end date.")]
    [GenericCompare(CompareToPropertyName="DateWorkStarted", OperatorName=Enums.GenericCompareOperator.GreaterThan, ErrorMessage="End Date must be occur after the start date.")]
    [Display(Name = "Closed Date")]
    [DataType(DataType.DateTime)]
    public Nullable<DateTime> DateClosed { get; set; }

其中一个注释是一个cusatom验证器,它将检查在结束日期(DateClosed)之后没有发生开始日期(DateWorkStarted)。

这是自定义验证器

$(document).ready(function () {
$.validator.addMethod("genericcompare", function (value, element, params) {
    // debugger;
    var propelename = params.split(",")[0];
    var operName = params.split(",")[1];
    if (params == undefined || params == null || params.length == 0 || value == undefined || value == null || value.length == 0 || propelename == undefined || propelename == null || propelename.length == 0 || operName == undefined || operName == null || operName.length == 0)
        return true;
    var valueOther = $(propelename).val();
    var val1 = (isNaN(value) ? Date.parse(value) : eval(value));
    var val2 = (isNaN(valueOther) ? Date.parse(valueOther) : eval(valueOther));

    if (operName == "GreaterThan")
        return val1 > val2;
    if (operName == "LessThan")
        return val1 < val2;
    if (operName == "GreaterThanOrEqual")
        return val1 >= val2;
    if (operName == "LessThanOrEqual")
        return val1 <= val2;
});

$.validator.unobtrusive.adapters.add("genericcompare", ["comparetopropertyname", "operatorname"], function (options) {
    options.rules["genericcompare"] = "#" + options.params.comparetopropertyname + "," + options.params.operatorname;
    options.messages["genericcompare"] = options.message;
});
});

现在,表单由2个按钮和一个常规提交按钮组成,该按钮提交表单并仅创建票证并保持打开状态。但是还有另一个按钮打开一个对话框,允许用户输入关闭的票证信息(在这种情况下输入开始和结束日期)。并且对话框上有一个按钮,它不仅使用主窗体中填写的字段而且还使用对话框中的字段来提交表单。这一切都很好。

我正在尝试做的是,当用户只是创建一个票证时,表单仍然会尝试并评估我的自定义验证器,因为此时我没有在日期中放置任何数据,验证将失败。如何在单击“创建故障单(提交)”按钮时禁用自定义验证器。

这是我认为会做的但是没有效果。 (我把它放在CreateButton的点击事件

        $("#CreateButton").click(function () {
            $("#CloseDescription").rules('remove');
            $("#DateWorkStarted").rules('remove');
            $("#DateClosed").rules('remove');
            $('#DateClosed').rules('remove', 'customcompare');

        });

我知道在那里有Datecompare特定的删除字符串,因为DateClosed看起来多余,因为规则('remove')应该处理特定选择器的所有规则但这是我最近的尝试,看看它是否有效(称之为抓住它吸管)。

任何帮助将不胜感激。 提前致谢, 迪安

2 个答案:

答案 0 :(得分:0)

您可以实现自己的必需if属性。

 public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
    private String PropertyName { get; set; }
    private Object DesiredValue { get; set; }
    private readonly RequiredAttribute _innerAttribute;

    public RequiredIfAttribute(String propertyName, Object desiredvalue)
    {
        PropertyName = propertyName;
        DesiredValue = desiredvalue;
        _innerAttribute = new RequiredAttribute();
    }

    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        var dependentValue = context.ObjectInstance.GetType().GetProperty(PropertyName).GetValue(context.ObjectInstance, null);

        if (dependentValue.ToString() == DesiredValue.ToString())
        {
            if (!_innerAttribute.IsValid(value))
            {
                return new ValidationResult(FormatErrorMessage(context.DisplayName), new[] { context.MemberName });
            }
        }
        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = ErrorMessageString,
            ValidationType = "requiredif",
        };
        rule.ValidationParameters["dependentproperty"] = (context as ViewContext).ViewData.TemplateInfo.GetFullHtmlFieldId(PropertyName);
        rule.ValidationParameters["desiredvalue"] = DesiredValue is bool ? DesiredValue.ToString().ToLower() : DesiredValue;

        yield return rule;
    }
}

用法

[RequiredIf("Condition", "Value", ErrorMessage="Error Message")]
    public string Property{ get; set; }

修改 您应该添加以下脚本,以便能够使用客户端验证。 (最好在单独的JS文件中)

$.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'desiredvalue'], function (options) {

    options.rules['requiredif'] = options.params;
    options.messages['requiredif'] = options.message;
});

$.validator.addMethod('requiredif', function (value, element, parameters) {

    var desiredvalue = parameters.desiredvalue;
    desiredvalue = (desiredvalue == null ? '' : desiredvalue).toString();
    var fieldId = parameters.dependentproperty.split('_')[0];
    var controlType = $("input[id$='" + fieldId + "']").attr("type");
    var actualvalue = {}
    if (controlType == "checkbox" || controlType == "radio") {
        var control = $("input[id$='" + fieldId + "']:checked");
        actualvalue = control.val();
    } else {
        actualvalue = $("#" + fieldId).val();
    }

    if (desiredvalue.indexOf(',') == -1) {
        if ($.trim(desiredvalue).toLowerCase() != $.trim(actualvalue).toLocaleLowerCase()) {
            var isValid = $.validator.methods.required.call(this, value, element, parameters);
            return isValid;
        }
    }
    else {

        if ($.trim(desiredvalue.split(',')[0].toLowerCase() != $.trim(actualvalue).toLocaleLowerCase() || $.trim(desiredvalue.split(',')[1].toLowerCase() != $.trim(actualvalue).toLocaleLowerCase())))
        {
            var isValid = $.validator.methods.required.call(this, value, element, parameters);
            return isValid;
        }
    }
    return true;
});

答案 1 :(得分:0)

好的,我想出来了。它最终成为我正在使用的实际CustomCompareAttribute类。除了实际的比较逻辑之外,我还需要检查传递给验证器(ClosedDate)的值是否为空。