ASP.NET MVC реализует пользовательский валидатор с использованием IClientValidatable - PullRequest
11 голосов
/ 27 ноября 2011

Я задаю подобный вопрос здесь , но в этом вопросе я использую другую реализацию, точно таким образом следующие коды показывают мои реализации:

Модель:

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

Сценарий:

$.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 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>

Часть Dom Create Page:

<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>

Я стараюсь, чтобы все реализации были такими же, как здесь , но они не работают на стороне клиента и требуют обратной передачи, у меня нет другой реализации, например, зарегистрируйтесь в global.asax как это , кто-нибудь знает об этом? Я действительно запутался, я попробовал 2 способа, но ни один из них не дал верного ответа.

1 Ответ

9 голосов
/ 27 ноября 2011

Вы испортили ваши скриптовые включения. В ваш _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 представляют один и тот же сценарий, первый - минимизированная версия. Но поскольку вы не включили сценарий 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>

Вы также можете добавить свой собственный скрипт jQuery.IsDateAfter.js в макет в конце, если хотите, если он используется во многих представлениях, а если нет, вы можете добавить его в представление:

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

Это единственный скрипт, который вы должны иметь в представлении. Вы должны удалить любые другие включения скрипта jquery.* со страниц редактирования и создания представления.

Примечание: вы также заметите, что я удалил все сценарии Microsoft*.js из вашего макета. Они устарели и больше не должны использоваться в ASP.NET MVC 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...