自定义验证属性中的客户端验证 - asp.net mvc 4

Posted

技术标签:

【中文标题】自定义验证属性中的客户端验证 - asp.net mvc 4【英文标题】:client-side validation in custom validation attribute - asp.net mvc 4 【发布时间】:2013-11-12 15:11:08 【问题描述】:

我在 Internet 上关注了一些文章和教程,以便创建一个自定义验证属性,该属性还支持 asp.net mvc 4 网站中的客户端验证。这是我到目前为止所拥有的:

RequiredIfAttribute.cs

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] //Added
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable

    private readonly string condition;
    private string propertyName; //Added

    public RequiredIfAttribute(string condition)
    
        this.condition = condition;
        this.propertyName = propertyName; //Added
    

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    
        PropertyInfo propertyInfo = validationContext.ObjectType.GetProperty(this.propertyName); //Added
        Delegate conditionFunction = CreateExpression(validationContext.ObjectType, _condition);
        bool conditionMet = (bool)conditionFunction.DynamicInvoke(validationContext.ObjectInstance);

        if (conditionMet)
        
            if (value == null)
            
                return new ValidationResult(FormatErrorMessage(null));
            
        

        return ValidationResult.Success;
    

    private Delegate CreateExpression(Type objectType, string expression)
    
        LambdaExpression lambdaExpression = System.Linq.Dynamic.DynamicExpression.ParseLambda(objectType, typeof(bool), expression); //Added
        Delegate function = lambdaExpression.Compile();
        return function;
    

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    
        var modelClientValidationRule = new ModelClientValidationRule
        
            ValidationType = "requiredif",
            ErrorMessage = ErrorMessage //Added
        ;

        modelClientValidationRule.ValidationParameters.Add("param", this.propertyName); //Added
        return new List<ModelClientValidationRule>  modelClientValidationRule ;
    

然后我将这个属性应用到这样的类的属性中

[RequiredIf("InAppPurchase == true", "InAppPurchase", ErrorMessage = "Please enter an in app purchase promotional price")] //Added "InAppPurchase"
public string InAppPurchasePromotionalPrice  get; set; 

public bool InAppPurchase  get; set; 

所以我想要做的是显示一条错误消息,当 InAppPurchase 字段为 true(这意味着在表单中检查)时需要字段 InAppPurchasePromotionalPrice。以下是视图的相关代码:

<div class="control-group">
                <label class="control-label" for="InAppPurchase">Does your app include In App Purchase?</label>
                <div class="controls">
                    @html.CheckBoxFor(o => o.InAppPurchase)
                    @Html.LabelFor(o => o.InAppPurchase, "Yes")
                </div>
            </div>
            <div class="control-group" id="InAppPurchasePromotionalPriceDiv" @(Model.InAppPurchase == true ? Html.Raw("style='display: block;'") : Html.Raw("style='display: none;'"))>
                <label class="control-label" for="InAppPurchasePromotionalPrice">App Friday Promotional Price for In App Purchase: </label>
                <div class="controls">
                    @Html.TextBoxFor(o => o.InAppPurchasePromotionalPrice, new  title = "This should be at the lowest price tier of free or $.99, just for your App Friday date." )
                    <span class="help-inline">
                        @Html.ValidationMessageFor(o => o.InAppPurchasePromotionalPrice)
                    </span>
                </div>
            </div>

此代码运行良好,但是当我提交表单时,服务器上会请求完整的帖子以显示消息。所以我创建了 javascript 代码来启用客户端验证:

requiredif.js

(function ($) 
    $.validator.addMethod('requiredif', function (value, element, params) 
        /*var inAppPurchase = $('#InAppPurchase').is(':checked');

        if (inAppPurchase) 
            return true;
        

        return false;*/

        var isChecked = $(param).is(':checked');

        if (isChecked) 
            return false;
        

        return true;
    , '');

    $.validator.unobtrusive.adapters.add('requiredif', ['param'], function (options) 
        options.rules["requiredif"] = '#' + options.params.param;
        options.messages['requiredif'] = options.message;
    );
)(jQuery);

这是我找到的msdn和教程中建议的方式

当然我还把需要的脚本插入到表单中:

    jquery.unobtrusive-ajax.min.js jquery.validate.min.js jquery.validate.unobtrusive.min.js requiredif.js

但是...客户端验证仍然不起作用。所以你能帮我找出我错过了什么吗?提前致谢。

【问题讨论】:

【参考方案1】:

看看这个:http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

使用本教程,我可以毫无问题地运行我的自定义验证代码。我可以在您的代码中发现的唯一区别是您创建 $.validator.unobtrusive.adapters.add 函数的方式。参数略有不同,但问题可能在于您没有定义适配器的rule 部分。

尝试使用这样的东西:

$.validator.unobtrusive.adapters.add("requiredif", ["requiredif"], function (options) 
    options.rules["requiredif"] = "#" + options.params.requiredif;
    options.messages["requiredif"] = options.message;
);

或者这个

$.validator.unobtrusive.adapters.add("requiredif", function (options) 
    options.rules["requiredif"] = "#" + options.element.name.replace('.', '_'); // mvc html helpers
    options.messages["requiredif"] = options.message;
);

关于rule(摘自链接):

此 HTML 元素的 jQuery 规则数组。预计适配器 为特定的 jQuery Validate 添加项目到此规则数组 它想要附加的验证器。名字就是jQuery的名字 验证规则,值为jQuery的参数值 验证规则。

【讨论】:

感谢您的回答。我将您的问题标记为答案,因为文章和您的代码帮助我了解了规则数组的使用并找到了解决方案。我编辑了我的问题,添加了现在在我的项目中完美运行的内容。谢谢 除非你和Giorgos的情况完全一样,否则你最好阅读Felipe开头提到的那篇文章。在我去读那篇文章之前,我什么也做不了。【参考方案2】:

值得注意的是,需要将[RequiredIf] 属性添加到视图模型中的第二个表单字段,以便客户端验证工作。

【讨论】:

以上是关于自定义验证属性中的客户端验证 - asp.net mvc 4的主要内容,如果未能解决你的问题,请参考以下文章

自定义属性的 ASP.NET MVC 客户端验证

剃须刀页面上自定义验证属性的 ASP.NET Core 客户端验证

ASP.Net Core MVC - 自定义属性的客户端验证

ASP.NET MVC3 - 自定义验证属性 -> 客户端损坏

使用 IClientModelValidator 在 ASP.NET Core 中使用参数自定义客户端验证属性

自定义客户端验证 jQuery 适配器不会在 ASP.Net Core 中触发