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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19726404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:45:46  来源:igfitidea点击:

client-side validation in custom validation attribute - asp.net mvc 4

c#jqueryasp.net-mvc-4jquery-validateunobtrusive-validation

提问by Giorgos Manoltzas

I have followed some articles and tutorials over the internet in order to create a custom validation attribute that also supports client-side validation in an asp.net mvc 4 website. This is what i have until now:

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

RequiredIfAttribute.cs

必需的IfAttribute.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 };
    }
}

Then i applied this attribute in a property of a class like this

然后我在这样的类的属性中应用了这个属性

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

So what i want to do is display an error message that field InAppPurchasePromotionalPrice is required when InAppPurchase field is true (that means checked in the form). The following is the relevant code form the view:

所以我想要做的是显示一条错误消息,当 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>

This code works perfectly but when i submit the form a full post is requested on the server in order to display the message. So i created JavaScript code to enable client-side validation:

这段代码完美无缺,但是当我提交表单时,会在服务器上请求完整的帖子以显示消息。所以我创建了 JavaScript 代码来启用客户端验证:

requiredif.js

必需的if.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);

This is the proposed way in msdn and tutorials i have found

这是我发现的 msdn 和教程中建议的方式

Of course i have also inserted the needed scripts in the form:

当然,我还以以下形式插入了所需的脚本:

  1. jquery.unobtrusive-ajax.min.js
  2. jquery.validate.min.js
  3. jquery.validate.unobtrusive.min.js
  4. requiredif.js
  1. jquery.unobtrusive-ajax.min.js
  2. jquery.validate.min.js
  3. jquery.validate.unobtrusive.min.js
  4. 必需的if.js

BUT...client side validation still does not work. So could you please help me find what am i missing? Thanks in advance.

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

采纳答案by Felipe Miosso

Take a look at this: http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

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

Using this tutorial I got my custom validation code running with no problem. The only difference I can spot in your code is the way you created the $.validator.unobtrusive.adapters.addfunction. The parameters are a little bit different but, maybe, the problem is just that you have not defined the rulepart of your adapter.

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

Try using something like this:

尝试使用这样的东西:

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

or this

或这个

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

About the rule(taken from the link):

关于rule(取自链接):

The jQuery rules array for this HTML element. The adapter is expected to add item(s) to this rules array for the specific jQuery Validate validators that it wants to attach. The name is the name of the jQuery Validate rule, and the value is the parameter values for the jQuery Validate rule.

此 HTML 元素的 jQuery 规则数组。适配器应为它想要附加的特定 jQuery Validate 验证器将项目添加到此规则数组。name 是 jQuery Validate 规则的名称,value 是 jQuery Validate 规则的参数值。

回答by Matthew Dresser

It's worth noting that the [RequiredIf]attribute needs to be added to the second form field in the view model in order for client validation to work.

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