Чего я хочу добиться:
- Чтобы отобразить отдельное сообщение проверки для неудачной проверки минимального возраста и одно для проверки максимального возраста
- Для хранения минимального и максимального возраста в одной области в виде целых чисел. Не в js/валидаторе... только в модели. который я надеюсь изменить, чтобы посмотреть файл конфигурации.
- Чтобы валидация работала с jquery ненавязчиво и на стороне сервера, и чтобы была в одном месте против модели (и обв какой-то jquery)
- Для включения с помощью аннотаций данных
- Я хотел проверить DOB как дату и время, чтобы пользователь не указал возраст как int. Если бы я это сделал, я мог бы использовать обозначение [Min] и [Max] для возраста. Это было недостаточно хорошо.
- Почему я не использовал обозначение диапазона. Я хотел запустить другое сообщение проверки для каждого минимального сбоя и максимального сбоя. Я смотрел на это и не смотрел. Мне также пришлось бы передать диапазон как datetime и его статику или что-то в этом роде, поэтому я не мог бы, например, сделать DateTime.Now.AddYears(-90).
Мои проблемы
- Я новичок в MVC, проверке JQuery и всей архитектуре MVC!
- То, что я придумал, работает. Однако, как вы можете видеть, код повторяется, и я хотел бы соответствовать DRY.
Мой первый хак заключался в том, чтобы передать значение, которое я проверяю, в сообщение проверки. Я обошел это, сделав...
[MaximumAgeCheck(90,"Для подачи заявки вам должно быть не более {0}")]
и внутри атрибута проверки
private readonly int _min;
private readonly string _defaultErrorMessage = "";
public MinimumAgeCheck(int min, string defaultErrorMessage)
: base(defaultErrorMessage)
{
_min = min;
_defaultErrorMessage = defaultErrorMessage.Replace("{0}", _min.ToString());
}
и я использовал его, например, так ..
return new ValidationResult(_defaultErrorMessage);
Я знаю, что это неправильный способ сделать это, и мне интересно, как это сделать лучше всего?
Второй взлом!
Я передаю два параметра проверки, к которым я хочу иметь доступ в методе jQuery.validator.addMethod....
Я попытался получить доступ к этим параметрам, выполнив следующие действия... params.[thevalueiadded], params[0]... и т. д., я даже вывел параметры в console.log, но он никогда не показывал мне все параметры, только первое значение как струна!
Моя работа заключалась в том, чтобы хранить переменные javascript вверху и загружать их из adapters.add.
Я, вероятно, мало что понимаю, поэтому вот код, который работает... Предупреждаю, он беспорядочный!
Свойство модели и аннотация данных
[Required(ErrorMessage = "Date of birth required")]
[Display(Name = "Date of Birth")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
[DataType(DataType.DateTime, ErrorMessage = "Date of birth should be in dd/mm/yyyy format")]
[MinimumAgeCheck(18,"You have to be at least {0} to apply")]
[MaximumAgeCheck(90,"You have to be at most {0} to apply")]
public DateTime? DateOfBirth { get; set; }
Проверка минимального и максимального возраста
атрибуты проверки
public class MinimumAgeCheck : ValidationAttribute, IClientValidatable
{
private readonly int _min;
private readonly string _defaultErrorMessage = "";
public MinimumAgeCheck(int min, string defaultErrorMessage)
: base(defaultErrorMessage)
{
_min = min;
_defaultErrorMessage = defaultErrorMessage.Replace("{0}", _min.ToString());
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
DateTime dtV = (DateTime)value;
long lTicks = DateTime.Now.Ticks - dtV.Ticks;
DateTime dtAge = new DateTime(lTicks);
if (!(dtAge.Year >= _min && dtAge.Year <= 30))
{
return new ValidationResult(_defaultErrorMessage);
}
return ValidationResult.Success;
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, _min);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule mcvrTwo = new ModelClientValidationRule();
mcvrTwo.ValidationType = "checkminimumage";
mcvrTwo.ErrorMessage = _defaultErrorMessage;
mcvrTwo.ValidationParameters.Add("todaysdate", DateTime.Now.ToString("dd/MM/yyyy"));
mcvrTwo.ValidationParameters.Add("lowerage", _min.ToString());
return new List<ModelClientValidationRule> { mcvrTwo };
}
}
public class MaximumAgeCheck : ValidationAttribute, IClientValidatable
{
private readonly int Max;
private readonly string _defaultErrorMessage = "";
public MaximumAgeCheck(int max, string defaultErrorMessage)
: base(defaultErrorMessage)
{
Max = max;
_defaultErrorMessage = defaultErrorMessage.Replace("{0}", Max.ToString());
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
DateTime dtV = (DateTime)value;
long lTicks = DateTime.Now.Ticks - dtV.Ticks;
DateTime dtAge = new DateTime(lTicks);
if (!(dtAge.Year >= Max && dtAge.Year <= 30))
{
return new ValidationResult(_defaultErrorMessage);
}
return ValidationResult.Success;
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,Max);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule mcvrTwo = new ModelClientValidationRule();
mcvrTwo.ValidationType = "checkmaximumage";
mcvrTwo.ErrorMessage = _defaultErrorMessage;
mcvrTwo.ValidationParameters.Add("todaysdate", DateTime.Now.ToString("dd/MM/yyyy"));
mcvrTwo.ValidationParameters.Add("upperage", Max.ToString());
return new List<ModelClientValidationRule> { mcvrTwo };
}
}
JQuery
(function ($) {
var mintodaysDateVal;
var maxtodaysDateVal;
var lowerageVal;
var upperageVal;
jQuery.validator.unobtrusive.adapters.add("checkminimumage", ['lowerage', 'todaysdate', 'upperage'], function (options) {
options.rules["checkminimumage"] = options.params;
mintodaysDateVal = options.params.todaysdate;
lowerageVal = options.params.lowerage;
options.messages["checkminimumage"] = options.message;
});
jQuery.validator.addMethod("checkminimumage", function (value, element, params) {
var currDate = mintodaysDateVal;
var sdoc = currDate.split('/');
var dobDate = value;
var sdob = dobDate.split('/');
//pass year,month,date in new Date object.
var vDOB = new Date(sdob[2], sdob[1] - 1, sdob[0]);
var vDOC = new Date(sdoc[2], sdoc[1] - 1, sdoc[0]);
//getAge user define function to calculate age.
var vYrs = getAge(vDOB, vDOC);
var result = false;
if (vYrs >= lowerageVal) { result = true; }
return result;
});
jQuery.validator.unobtrusive.adapters.add("checkmaximumage", ['lowerage', 'todaysdate', 'upperage'], function (options) {
options.rules["checkmaximumage"] = options.params;
maxtodaysDateVal = options.params.todaysdate;
upperageVal = options.params.upperage;
options.messages["checkmaximumage"] = options.message;
});
jQuery.validator.addMethod("checkmaximumage", function (value, element, params) {
var currDate = maxtodaysDateVal;
var sdoc = currDate.split('/');
var dobDate = value;
var sdob = dobDate.split('/');
var vDOB = new Date(sdob[2], sdob[1] - 1, sdob[0]);
var vDOC = new Date(sdoc[2], sdoc[1] - 1, sdoc[0]);
var vYrs = getAge(vDOB, vDOC);
var result = false;
if (vYrs <= upperageVal) { result = true; }
return result;
});
function getAge(oldDate, currDate) {
return currDate.getFullYear() - oldDate.getFullYear();
}
} (jQuery));
Я надеюсь, что это имеет смысл, я прочитал его, и он довольно искажен... так что я буду рад ответить на любые комментарии.