我无法在表单中使用datetime验证字段

时间:2015-03-10 07:49:37

标签: c# jquery asp.net asp.net-mvc unobtrusive-validation

我正在使用这个对象:

[Required]
[Display(Name = "AuditDate", ResourceType = typeof(Resources.Audit))]
[DisplayFormat(DataFormatString = "{dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime dateAudit { get; set; }

在我的表格的这一部分:

@Html.TextBox("dateAudit", String.Format("{0:d}", Model.dateAudit.ToString("dd'/'MM'/'yyyy"), new { @class = "form-control" }))

当我尝试输入日期时,我无法提交表单(出现DatePicker对话框),因为该字段存在问题。我在字段中添加了ValidationMessageFor,告诉我该字段不包含有效日期:

@Html.ValidationMessageFor(model => model.dateAudit, "", new { @class = "text-danger" })

这是此时为该字段生成的HTML错误消息:

<input data-val="true" data-val-date="The field Date must be a date." data-val-required="The field Date is required." id="dateAudit" name="dateAudit" type="text" value="10/03/2015" class="hasDatepicker input-validation-error">

我还尝试在配置文件中为所有应用程序设置文化:

<globalization uiCulture="fr-FR" culture="fr-FR" />

如果我选择3月1日的日期,格式为01/03/2015,那么没有问题,模型绑定会识别它,但是当我选择3月20日时,该字段无法验证(I怀疑它认为我试图输入20作为月份。

我发现this library有助于客户端验证,但看起来它并不符合所有浏览器,所以我无法使用它。我考虑完全放弃客户端验证,只验证后端的日期字段。

感谢您的帮助。

编辑:我忘了建议你使用jquery ui重新定义datepicker:

/* French initialisation for the jQuery UI date picker plugin. */
/* Written by Keith Wood (kbwood{at}iinet.com.au),
              Stéphane Nahmani (sholby@sholby.net),
              Stéphane Raimbault <stephane.raimbault@gmail.com> */
(function (factory) {
    if (typeof define === "function" && define.amd) {

        // AMD. Register as an anonymous module.
        define(["../datepicker"], factory);
    } else {

        // Browser globals
        factory(jQuery.datepicker);
    }
}(function (datepicker) {

    datepicker.regional['fr'] = {
        closeText: 'Fermer',
        prevText: 'Précédent',
        nextText: 'Suivant',
        currentText: 'Aujourd\'hui',
        monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
            'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
        monthNamesShort: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',
            'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
        dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
        dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
        dayNamesMin: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
        weekHeader: 'Sem.',
        dateFormat: 'dd/mm/yy',
        firstDay: 1,
        isRTL: false,
        showMonthAfterYear: false,
        yearSuffix: ''
    };
    datepicker.setDefaults(datepicker.regional['fr']);

    return datepicker.regional['fr'];

}));

4 个答案:

答案 0 :(得分:1)

您可以创建自己的方法来覆盖jquery.validator默认方法。请注意,以下代码对于您所需要的内容可能过于苛刻(它是我自己的@Html.DatePicker()帮助程序插件的一部分,它根据服务器CultureInfo呈现日期选择器

// Override default date validator format to allow culture specific format
$.validator.methods.date = function (value, element) {
  return this.optional(element) || globalDate(value).isValid();
};

注意:请勿在{{1​​}}

中包含上述方法
document.ready()

编辑:基于已编辑的问题(OP正在使用jQuery UI日期选择器),它可能只是

Date.prototype.isValid = function () {
  return !isNaN(this.getTime());
}

var inputFormat = 'dd/MM/yyyy';

// datepicker.prototype.globalDate = function (value) {
function globalDate(value) {
  // Initialise a new date
  var date = new Date(0);
  if (value == undefined) {
    // Return todays date
    return date; // adjust to suit your needs
  }
  // Get the components of the format
  // The separator can be forward slash, hyphen, dot and/or space
  var regex = new RegExp(/([dMy]+)([\s/.-]+)([dMy]+)([\s/.-]+)([dMy]+)/);
  var format = regex.exec(inputFormat);
  // Get the components of the value
  regex = new RegExp(/(\d+)([\s/.-]+)(\d+)([\s/.-]+)(\d+)/);
  value = regex.exec(value);
  // Check the value is valid
  if (value === null || value[2] !== format[2] || value[4] !== format[4]) {
    // Its not valid
    date.setTime(Number.NaN);
    return date;
  }
  // TODO: What if year entered as 2 digits?
  var day = Number.NaN;
  var month = Number.NaN;
  var year = Number.NAN;
  if (format[1].charAt(0) === 'd') {
    // little-endian (day, month, year)
    day = parseInt(value[1]);
    month = parseInt(value[3]) - 1;
    year = parseInt(value[5]);
  } else if (format[1].charAt(0) === 'M') {
    // middle-endian (month, day, year)
    day = parseInt(value[3]);
    month = parseInt(value[1]) - 1;
    year = parseInt(value[5]);
  } else {
    // big endian (year, month, day)
    day = parseInt(value[5]);
    month = parseInt(value[3]) - 1;
    year = parseInt(value[1]);
  }
  date.setFullYear(year);
  date.setMonth(month);
  date.setDate(day);
  // Check its valid
  if (date.getDate() !== day || date.getMonth() !== month || date.getFullYear() !== year) {
    date.setTime(Number.NaN);
    return date;
  }
  return date;
}

附注:建议您使用强类型帮助程序并传递格式字符串

$.validator.addMethod('date', function (value, element) {
  if (this.optional(element)) {
    return true;
  }
  var valid = true;
  try {
    $.datepicker.parseDate('dd/mm/yy', value);
  }
  catch (err) {
    valid = false;
  }
  return valid;
});
$('#dateAudit').datepicker({ dateFormat: 'dd/mm/yy' });

答案 1 :(得分:0)

如果您不想使用 Globalize 库,例如@StephenMuecke建议,您可以在某种初始化脚本或文档头部设置jquery datepicker的默认值:< / p>

$.datepicker.regional['fr'] = {
    clearText: 'Effacer', clearStatus: '',
    closeText: 'Fermer', closeStatus: 'Fermer sans modifier',
    prevText: '&lt;Préc', prevStatus: 'Voir le mois précédent',
    nextText: 'Suiv&gt;', nextStatus: 'Voir le mois suivant',
    currentText: 'Courant', currentStatus: 'Voir le mois courant',
    monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
    'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
    monthNamesShort: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun',
    'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'],
    monthStatus: 'Voir un autre mois', yearStatus: 'Voir un autre année',
    weekHeader: 'Sm', weekStatus: '',
    dayNames: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
    dayNamesShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
    dayNamesMin: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],
    dayStatus: 'Utiliser DD comme premier jour de la semaine', dateStatus: 'Choisir le DD, MM d',
    dateFormat: 'dd/mm/yy', firstDay: 0,
    initStatus: 'Choisir la date', isRTL: false
};
$.datepicker.setDefaults($.datepicker.regional['fr']);

答案 2 :(得分:0)

这是因为您的浏览器未配置为根据法语格式设置日期格式:dd / MM / yyyy

请告诉您的浏览器是法语

 $.datepicker.setDefaults( $.datepicker.regional[ "fr" ] );

此外,您可能需要使用EditorFor帮助程序而不是TextBoxFor,因为EditorForTextBoxFor

更智能
   @Html.EditorFor(model=>model.dateAudit)

注意:您可能需要编辑器和显示模板来设计此帮助程序。

答案 3 :(得分:-1)

我已经要求删除日期字段的验证,因为我不想使用globalize trhird聚会模块,因为兼容性很强(browser-support for globalize module

我在stackoverflow: ASP.NET MVC 4 avoid generation of data-val-date for datetime中看到了糟糕但有效的解决方案:

$.validator.addMethod('date', function (value, element) {
            return true; // since MVC data-val-date is put on EVERY vm date property. Default implementation does not allow for multiple cultures...
        });

我等待更好的解决方案,但这是我的临时解决方案......