Должен ли ValidationAttribute иметь одно сообщение об ошибке? - PullRequest
0 голосов
/ 11 апреля 2019

ValidationAttribute.ErrorMessage - это строка, означающая, что на ValidationAttribute должна быть одна ошибка.

Скажем, у меня есть такой код:

[BeforeThan(nameof(EndTime), nameof(EndTime2), ErrorMessage = "StartTime should before than EndTime and EndTime2")]
public DateTime StartTime { get; set; }

и IsValidметод, подобный этому:

protected override ValidationResult IsValid(object startTime, ValidationContext validationContext)
{
    var endTimePropertyValue = validationContext.ObjectType.GetProperty(EndTimePropertyName)
          .GetValue(validationContext.ObjectInstance);

    if (startTime != null && startTime is DateTime
        & endTimePropertyValue != null && endTimePropertyValue is DateTime)
    {
        if ((DateTime)startTime > (DateTime)endTimePropertyValue)
        {
            return new ValidationResult(ErrorMessage);
        }
    }

    return ValidationResult.Success;
}

На стороне клиента есть ненавязчивый JavaScript.

Скажем, я хотел добавить больше логики, чтобы сказать;если конечная дата 1 совпадает с конечной датой 2, сообщите другое сообщение об ошибке.

  1. Создайте для этого отдельный атрибут, т.е. имейте два атрибута.
  2. Измените приведенный выше код, чтобывернуть два разных сообщения об ошибке в зависимости от сценария

Пожалуйста, помните, что я использую навязчивый JavaScript на стороне клиента.

1 Ответ

0 голосов
/ 11 апреля 2019

Нет явной необходимости использовать только свойство ErrorMessage для установки текста ошибки.Вы можете ввести дополнительные свойства, чтобы указать, нужно ли проверять, равны ли даты

public string ErrorMessage2 { get; set; }

protected override ValidationResult IsValid(object startTime, ValidationContext validationContext)
{
    var endTimePropertyValue = validationContext.ObjectType.GetProperty(EndTimePropertyName)
            .GetValue(validationContext.ObjectInstance);

    if (startTime != null && startTime is DateTime
        & endTimePropertyValue != null && endTimePropertyValue is DateTime)
    {
        DateTime startDateTime = (DateTime)startTime;
        DateTime endDateTime = (DateTime)endTimePropertyValue;

        //if second error message is not empty we check if date are the same
        bool checkIfEqual = !string.IsNullOrEmpty(ErrorMessage2);

        if (checkIfEqual && startDateTime == endDateTime)
        {
            return new ValidationResult(ErrorMessage2);
        }
        else if (startDateTime > endDateTime)
        {
            return new ValidationResult(ErrorMessage);
        }
    }

    return ValidationResult.Success;
}

. Можно ли вообще отказаться от ErrorMessage и использовать жестко закодированные строки

private const string StartDateBefore = "StartTime should before than EndTime and EndTime2";
private const string StartDateEqual = "StartTime is equal to EndTime";

public bool CheckIfEqual { get; set; }

protected override ValidationResult IsValid(object startTime, ValidationContext validationContext)
{
    var endTimePropertyValue = validationContext.ObjectType.GetProperty(EndTimePropertyName)
            .GetValue(validationContext.ObjectInstance);

    if (startTime != null && startTime is DateTime
        & endTimePropertyValue != null && endTimePropertyValue is DateTime)
    {
        DateTime startDateTime = (DateTime)startTime;
        DateTime endDateTime = (DateTime)endTimePropertyValue;

        if (CheckIfEqual && startDateTime == endDateTime)
        {
            return new ValidationResult(StartDateEqual); //error message when dates are equal
        }
        else if (startDateTime > endDateTime)
        {
            return new ValidationResult(StartDateBefore); //error message when start date is after enddate
        }
    }

    return ValidationResult.Success;
}

Использование

[SomeValidation(nameof(EndDate), CheckIfEqual = true)]
public DateTime StartDate { get; set; }

Чтобы этот атрибут валидации работал с валидацией на стороне клиента, вам необходимо реализовать интерфейс IClientModelValidator, как описано здесь .

public void AddValidation(ClientModelValidationContext context)
{
    //"beforedate" and "equaldate" will be added as custom validators
    //for unobtrusive validation
    context.Attributes.Add("data-val-beforedate", StartDateBefore);

    if (CheckIfEqual)
        context.Attributes.Add("data-val-equaldate", StartDateEqual);
}

С этим кодом реализовано input будет содержать дополнительные атрибуты с соответствующими сообщениями об ошибках.Теперь нам нужно реализовать собственные валидаторы в javascript и скопировать логику валидации из C# code

//add "beforedate" custom validator
$.validator.addMethod("beforedate", function (value, element, parameters) {
    var startDate = new Date(value);
    var endDate = new Date($("#EndDate").val());

    //if condition is true then value considered valid
    return endDate >= startDate;
});

//add unobtrusive adapter to run "beforedate" validation
$.validator.unobtrusive.adapters.add("beforedate", [], function (options) {
    options.rules.beforedate = {};
    options.messages["beforedate"] = options.message; //save error message passed from C#
});

$.validator.addMethod("equaldate", function (value, element, parameters) {
    var startDate = new Date(value);
    var endDate = new Date($("#EndDate").val());

    return endDate.getTime() != startDate.getTime();
});

$.validator.unobtrusive.adapters.add("equaldate", [], function (options) {
    options.rules.equaldate = {};
    options.messages["equaldate"] = options.message;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...