我一直在努力让自定义客户端网站日期验证工作,到目前为止我似乎无法使其正常工作。
我有一个像这样定义的自定义日期编辑器:
@model DateTime?
@{
if (Model.HasValue)
{
int day = Model.Value.Day;
int month = Model.Value.Month;
int year = Model.Value.Year;
}
List<SelectListItem> days = new List<SelectListItem>();
for (int i = 1; i <= 31; i++)
{
days.Add(new SelectListItem { Text = i.ToString(), Value = i.ToString(), Selected = Model.HasValue && Model.Value.Day == i});
}
List<SelectListItem> months = new List<SelectListItem>();
for (int i = 1; i <= 12; i++)
{
months.Add(new SelectListItem { Text = i.ToString(), Value = i.ToString(), Selected = Model.HasValue && Model.Value.Month == i});
}
List<SelectListItem> years = new List<SelectListItem>();
var minYear = DateTime.Now.Year - 100;
var maxYear = DateTime.Now.Year - 18;
for (int i = maxYear; i >= minYear; i--)
{
years.Add(new SelectListItem { Text = i.ToString(), Value = i.ToString(), Selected = Model.HasValue && Model.Value.Year == i });
}
}
@Html.DropDownList("days", days, "Day", new { @class="form__select" } )
@Html.DropDownList("months", months, "Month", new { @class="form__select" } )
@Html.DropDownList("years", years, "Year", new { @class="form__select" } )
我有一个自定义验证属性,如下所示:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class DoBValidatorAttribute : ValidationAttribute, IClientValidatable
{
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
List<ModelClientValidationRule> clientRules = new List<ModelClientValidationRule>();
ModelClientValidationRule validDateRule = new ModelClientValidationRule
{
ErrorMessage = "Please enter a valid date.",
ValidationType = "validdate"
};
validDateRule.ValidationParameters.Add("dayelement", metadata.PropertyName + ".days");
validDateRule.ValidationParameters.Add("monthelement", metadata.PropertyName + ".months");
validDateRule.ValidationParameters.Add("yearelement", metadata.PropertyName + ".years");
clientRules.Add(validDateRule);
return clientRules;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
DateTime dateResult;
int day = Convert.ToInt32(validationContext.Items["days"]);
int month = Convert.ToInt32(validationContext.Items["months"]);
int year = Convert.ToInt32(validationContext.Items["years"]);
// Put date parts together and check is valid...
if (DateTime.TryParse(year + "/" + month + "/" + day, out dateResult))
{
return ValidationResult.Success;
}
// Not valid
return new ValidationResult(string.Format(ErrorMessageString, validationContext.DisplayName));
}
}
为了(尝试)并将所有这些连接在一起,我在我的JavaScript中也有这个:
jQuery.validator.unobtrusive.adapters.add(
'validdate', // notice this is coming from how you named your validation rule
['dayelement'],
['monthelement'],
['yearelement'],
function (options) {
options.rules['datepartcheck'] = options.params;
options.messages['datepartcheck'] = options.message;
}
);
jQuery.validator.addMethod('datepartcheck', function (value, element, params) {
var year = params[2];
var month = params[1];
var day = params[0];
var birthDate = year + '/' + month-1 + '/' + day;
var isValid = true;
try {
// datepicker is a part of jqueryUI.
// include it and you can take advantage of .parseDate:
$.datepicker.parseDate('yy/mm/dd', birthDate);
}
catch (error) {
isValid = false;
}
return isValid;
}, '');
我在所有这些方法上都设置了一个断点,但是GetClientValidationRules
方法从未被调用,我认为这意味着规则永远不会被应用于HTML。
我在这里做错了什么?我只是想不出来。如果可以,我会抛弃所有这些并使用普通的日期选择器,但客户端坚持这种格式。
更新
为了清楚生成的HTML,生成的控件是三个<select>
输入。
我想知道在我的模型上将其拆分为三个单独的int
属性是否更好,而是使用范围验证器。