MVC4客户端站点拆分下拉日期验证

时间:2015-08-08 11:30:55

标签: javascript jquery asp.net-mvc validation

我一直在努力让自定义客户端网站日期验证工作,到目前为止我似乎无法使其正常工作。

我有一个像这样定义的自定义日期编辑器:

@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属性是否更好,而是使用范围验证器。

0 个答案:

没有答案