MVC3 ненавязчивая проверка даты на пользовательской форматированной дате

у меня есть поле даты (я использую jQuery ui datepicker) в форме, которую я отформатировал, например:

ViewModel

[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime FooDate { get; set; }

посмотреть

@Html.EditorFor(m => m.FooDate)

это правильно показывает дату так, как я хочу, например,09-Nov-2011

проблема, которую я получаю, возникает, когда я нажимаю submit. Он продолжает говорить мне, что дата недействительна.... Действительно, глупо!

есть ли способ, я могу получить jQuery / ненавязчивый javascript, чтобы игнорировать это поле или позволить этому формату пройти? До сих пор единственный способ заставить форму работать-это не форматировать дату или использовать для нее формат {0:d}.

редактировать: Я создал совершенно отдельный макет+Вид+Контроллер+модель для тестирования этой глупой вещи. Все еще не работает в IE/Safari. У меня есть последний jquery.проверка / ненавязчивые файлы из nuget.

мой layout пусто. Он просто загружает следующее файлы:

"jquery-1.7.min.js"
"jquery-ui-1.8.16.min.js"
"jquery.validate.min.js"
"jquery.validate.unobtrusive.min.js"

мой TestViewModel прост:

public class TestViewModel
{
    [Display(Name = "Test Date:")]
    [DisplayFormat(DataFormatString = "{0:dd/MMM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? TestDate { get; set; }
}

мой TestController идет следующим образом:

public class TestController : Controller
{
    public ActionResult Index()
    {
        var m = new TestViewModel();
        m.TestDate = DateTime.Now;
        return View(m);
    }
}

Мое Мнение:

@using (Html.BeginForm())
{
    ViewContext.FormContext.ValidationSummaryId = "valSumId";
    @Html.ValidationSummary(false, "The following errors were found:");
    @Html.AntiForgeryToken()

    @Html.LabelFor(m => m.TestDate)
    <input type="date" id="TestDate" value="@Model.TestDate.Value.ToString("dd/MMM/yyyy")" />
    <input type="submit" />
}

нет норм.

вы знаете, что раздражает? Если я изменюсь TestDate к строке, он все еще терпит неудачу.

10 ответов


Я думаю, что есть проблема с дефиса ("-") в строке формата:

[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]

Кажется, что ненавязчивая проверка не принимает дефис для форматирования даты по умолчанию.

в моем случае мне пришлось добавить пользовательский метод на стороне клиента:

$.validator.methods.date = function (value, element) {
    var s = value;
    s = value.replace(/\-/g, '/');

    return this.optional(element) || !/Invalid|NaN/.test(new Date(s));
};

как реализовано здесь


похоже С помощью jQuery.утверждать.ненавязчивый проблема input type="date". Это должно быть ошибка, которая возникает только в IE и Safari.

когда я удалил ненавязчивый файл js, он отправил форму в порядке. Когда я добавил ненавязчивый JS-файл обратно и изменил тип ввода на текст, он сработал.

досадная ошибка. Нужно исправить.


здесь действительно две вещи:

  1. проверка на стороне клиента
  2. проверка на стороне сервера

оба должны использовать один и тот же формат для работы. Давайте сначала рассмотрим проверку на стороне сервера. Вы можете написать пользовательскую привязку модели для полей DateTime, которая будет использовать формат, указанный для отображения при их привязке. Вот это пример такой модели binder.

Далее мы должны иметь дело с клиентом боковая проверка. Для этого вы можете написать пользовательское правило, которое будет прикреплено к данным элементам:

<script type="text/javascript">
    $.validator.addMethod(
        'myDateFormat', function (value, element) {
            // TODO: put your validation logic here that will parse the string
            // and validate it
            return false;
        },
        'Please enter a date in the format dd-MMM-yyyy'
    );

    $(function () {
        // we attach the custom validation rule to the given input element
        $('#FooDate').rules('add', 'myDateFormat');
    });
</script>

вы также можете использовать адаптеры с пользовательским атрибутом.


для моего случая я использую текстовое поле для даты, поэтому это не вызвало проблемы для проверки jQuery:

 <div class="editor-field">
    @Html.TextBox("ExpiryDate", String.Format("{0:ddd, dd MMM yyyy}", DateTime.Now), new { id = "expirydate" })
    @Html.ValidationMessageFor(model => model.ExpiryDate)
</div>

Так почему бы вам не попробовать отформатировать дату так, а не использовать тип ввода=date?

надеюсь, что это поможет :)


на самом деле это не ошибка в браузере, проблемы проверки клиента могут возникнуть из-за ошибки MVC (даже в MVC 5) в С помощью jQuery.утверждать.ненавязчивый.минута.js, который не принимает формат даты и времени в любом случае. К сожалению, вы должны решить его вручную.

мое, наконец, рабочее решение:

вы должны включить раньше:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

вы можете установить время.js использование:

Install-Package Moment.js

и тогда вы можете наконец, добавьте исправление для парсера формата даты:

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});

Как опубликовал лукьер, могут быть проблемы, связанные с С помощью jQuery.подтверждать.*минута.js файлы, особенно если вы добавили свою собственную проверку в эти файлы. Простой ответ, который я нашел, работал для меня, когда система окончательного выпуска не смогла проверить даты в IE (Chrome работал без проблем), состоял в том, чтобы просто удалить предварительно упакованные мини-файлы проверки вообще и позволить зверю обрабатывать его собственное минирование из "главных" файлов. Жаль только, что у меня не было связи. ответ лукьера на решение ранее...

(Я, вероятно, опубликую это как комментарий, но, по-видимому, я еще не получил достаточно репутации:должен стараться!)


вы пытались просто изменить тип на:

@Html.TextBoxFor(model => model.startDate, new { @class = "date" })

У меня была такая же проблема с EditorFor... поэтому я изменил его на это, а затем применил свой jQuery datepicker к классу "дата", добавленному в текстовое поле.


просто хотел сделать небольшой комментарий к этой строке, если у кого-то еще возникнут проблемы с этим позже:

<input type="date" id="TestDate" value="@Model.TestDate.Value.ToString("dd/MMM/yyyy")" />

в некоторых случаях (по крайней мере, мой случай ранее) это будет переводиться в этот формат: "01.01.2012", потому что с некоторыми культурами вы не можете указать такие косые черты, чтобы фактически получить его в таком формате, он просто превратит их в точки, поэтому мне пришлось написать:

@Model.TestDate.Value.ToString("dd\/MMM\/yyyy");

, который дал мне "01/01/2012".


довольно старая эта нить. Только что приземлился здесь с похожими проблемами. В другом потоке я прочитал, что может быть проблема с несовместимостью версий всеми этими *.JS библиотеки как-то involfed в проверку. Возможно, следующая ссылка может помочь другим читателям landig здесь: https://stackoverflow.com/a/16551039

надеюсь, что это помогает


у меня была та же проблема, это сводит меня с ума! В принципе, проверка mvc всегда будет отображать объекты DateTime, требующие значения в текстовом поле. Почему? Потому что это напрямую связано с