ASP.NET MVC реализует использование пользовательского валидатора IClientValidatable
Я задаю аналогичный вопрос здесь, но в этом вопросе я использую другую реализацию, а именно таким образом следующее коды показывают мои реализации:
Модель:
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; }
}
Пользовательский валидатор
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);
}, '');
И моя страница _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>
конечно, в разделе "Редактировать и создавать страницы просмотра" другим источником 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>
Часть страницы создания страницы:
<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>
Я стараюсь, чтобы все реализации были такими же, как здесь, но которые не работают на стороне клиента и требуют обратной передачи, у меня нет другой реализации, например register в global.asax
например , знает ли кто-нибудь об этом? Я действительно смутился, я пробовал 2 пути, но никто из них не дал истинного ответа.
Ответы
Ответ 1
Вы перепутали свои включения script. В вашем _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>
Теперь, очевидно, jquery.validate.min.js
и jquery.validate.js
представляет тот же самый script, первый из которых является мини-версией. Но поскольку вы не включили jquery.validate.unobtrusive.js
script (это сделано намного позже в вашем представлении), ваш пользовательский jQuery.IsDateAfter.js
script будет содержать ошибки, поскольку он не будет знать о $.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>
Вы также можете добавить свой собственный jQuery.IsDateAfter.js
script к макету в конце, если хотите, если он используется во многих представлениях, и если вы не можете добавить его в представление:
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script>
Это единственный script, который вы должны иметь в представлении. Вы должны удалить любые другие вкладки jquery.*
script на страницах редактирования и создания.
Примечание. Вы также заметите, что я удалил все сценарии Microsoft*.js
из вашего макета. Они устарели и больше не должны использоваться в ASP.NET MVC 3.