javascript ASP.NET MVC 实现自定义验证器使用 IClientValidatable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8284207/
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-10-26 02:55:01  来源:igfitidea点击:

ASP.NET MVC implement custom validator use IClientValidatable

javascriptasp.net-mvcasp.net-mvc-3razorunobtrusive-validation

提问by Saeid

I ask similar question herebut in this question I use another implementation, exactly this waythe following codes show my implementations:

在这里问了类似的问题但在这个问题中我使用了另一个实现,正是这样,以下代码显示了我的实现:

Model:

模型:

public class Department {

    public long Id { get; set; }

    [IsDateAfter("Date2", true, ErrorMessage = "O My")]
    public DateTime Date1 { get; set; }
    public DateTime Date2 { get; set; }
    public string Name1 { get; set; }
    public string Name2 { get; set; }

}

Custom Validator:

自定义验证器:

public sealed class IsDateAfter : ValidationAttribute, IClientValidatable {

    private readonly string testedPropertyName;
    private readonly bool allowEqualDates;

    public IsDateAfter(string testedPropertyName, bool allowEqualDates = false)
  {
        this.testedPropertyName = testedPropertyName;
        this.allowEqualDates = allowEqualDates;
    }

    protected override ValidationResult IsValid(object value, ValidationContext
 validationContext) {
        var propertyTestedInfo = 
validationContext.ObjectType.GetProperty(this.testedPropertyName);
        if (propertyTestedInfo == null) {
            return new ValidationResult(string.Format("unknown property
 {0}", this.testedPropertyName));
        }

        var propertyTestedValue =
 propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);

        if (value == null || !(value is DateTime)) {
            return ValidationResult.Success;
        }

        if (propertyTestedValue == null || !(propertyTestedValue is
 DateTime)) {
            return ValidationResult.Success;
        }

        // Compare values
        if ((DateTime)value >= (DateTime)propertyTestedValue) {
            if (this.allowEqualDates) {
                return ValidationResult.Success;
            }
            if ((DateTime)value > (DateTime)propertyTestedValue) {
                return ValidationResult.Success;
            }
        }

        return new
 ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }

    public IEnumerable<ModelClientValidationRule> 
GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
        var rule = new ModelClientValidationRule {
            ErrorMessage = this.ErrorMessageString,
            ValidationType = "isdateafter"
        };
        rule.ValidationParameters["propertytested"] =
 this.testedPropertyName;
        rule.ValidationParameters["allowequaldates"] =
 this.allowEqualDates;
        yield return rule;
    }
}

Script:

脚本:

$.validator.unobtrusive.adapters.add(
'isdateafter', ['propertytested', 'allowequaldates'], function (options) {
    options.rules['isdateafter'] = options.params;
    options.messages['isdateafter'] = options.message;
});
$.validator.addMethod("isdateafter", function (value, element, params) {
alert(params.propertytested);
var startdatevalue = $('input[name="' + params.propertytested + '"]').val();
if (!value || !startdatevalue) return true;
return (params.allowequaldates) ? Date.parse(startdatevalue) <= Date.parse(value) :
 Date.parse(startdatevalue) < Date.parse(value);
}, '');

And My _Layout page (Master page)

和我的 _Layout 页(母版页)

<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">
 </script>
<script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript">
 </script>
<script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript">
 </script>
<script src="@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" 
 type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" 
 type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript">
 </script>
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" 
 type="text/javascript"></script>
</head>
<body>
<div class="page">
    <div id="header">
        <div id="title">
            <h1>
                My MVC Application</h1>
        </div>
        <div id="logindisplay">
            @Html.Partial("_LogOnPartial")
        </div>
        <div id="menucontainer">
            <ul id="menu">
        <li>@Html.ActionLink("Departments", "Index", "Department")</li>
            </ul>
        </div>
    </div>
    <div id="main">
        @RenderBody()
    </div>
    <div id="footer">
    </div>
</div>
</body>
</html>

of course in Edit And Create View pages the other script source are as following:

当然在编辑和创建视图页面中,其他脚本源如下:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript">
</script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>

A part of Create Page Dom:

创建页面 Dom 的一部分:

<fieldset>
<legend>Department</legend>
<div class="editor-label">
<label for="Date1">Date1</label>
</div>
<div class="editor-field">
<input id="Date1" class="text-box single-line valid" type="text" value="" name="Date1"
 data-val-required="The Date1 field is required." data-val-isdateafter-
 propertytested="Date2" data-val-isdateafter-allowequaldates="False" data-val-
isdateafter="O My" data-val="true">
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-
  for="Date1"></span>
</div>
<div class="editor-label">
<label for="Date2">Date2</label>
</div>
<div class="editor-field">
<input id="Date2" class="text-box single-line valid" type="text" value="" name="Date2"
 data-val-required="The Date2 field is required." data-val="true">
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-
for="Date2"></span>
</div>

I try All of implementation be the same as herebut that not work in client side and need to postback, I don't have any other implementation for example register in global.asax like this, Does any one know about it? I really confused, I tried 2 way but none of them give the true answer.

我尝试所有实现都与此处相同,但在客户端不起作用并且需要回发,我没有任何其他实现,例如像这样在 global.asax 中注册,有人知道吗?我真的很困惑,我尝试了 2 种方式,但没有一个给出真正的答案。

采纳答案by Darin Dimitrov

You have messed up your script inclusions. In your _Layout you have included the following scripts in that order:

你搞砸了你的脚本包含。在您的 _Layout 中,您按顺序包含了以下脚本:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script>

Now obviously jquery.validate.min.jsand jquery.validate.jsrepresents the same script, the first being the minified version. But since you haven't included the jquery.validate.unobtrusive.jsscript (this is done much later in your view), your custom jQuery.IsDateAfter.jsscript will contain errors since it will not know about the $.validator.unobtrusive.adaptersobject that you are using. So here's how the scripts in your layout should look:

现在很明显jquery.validate.min.jsjquery.validate.js代表相同的脚本,第一个是缩小版本。但是由于您没有包含jquery.validate.unobtrusive.js脚本(这在您的视图中稍后完成),您的自定义jQuery.IsDateAfter.js脚本将包含错误,因为它不知道$.validator.unobtrusive.adapters您正在使用的对象。因此,您的布局中的脚本应如下所示:

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

You could also add your custom jQuery.IsDateAfter.jsscript to the layout at the end if you wish in case it is used in many views and if not you could add it to the view:

jQuery.IsDateAfter.js如果您愿意,您还可以在最后将您的自定义脚本添加到布局中,以防它在许多视图中使用,如果没有,您可以将其添加到视图中:

<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script>

That's the only script you should have in the view. You should remove any other jquery.*script inclusions from your Edit And Create View pages.

这是您应该在视图中拥有的唯一脚本。您应该jquery.*从“编辑和创建视图”页面中删除任何其他脚本内容。

Remark: you will also notice that I have removed all Microsoft*.jsscripts from your Layout. They are obsolete and should no longer be used in ASP.NET MVC 3.

备注:您还会注意到我Microsoft*.js已从您的布局中删除了所有脚本。它们已过时,不应再在 ASP.NET MVC 3 中使用。