Я до сих пор довольно новичок в ASP.NET и MVC, и, несмотря на дни поиска и экспериментирования, я рисую пробел, чтобы наилучшим образом решить эту проблему ,ASP.NET MVC - сохранение недопустимого выбора DateTime с 3 раскрывающимися списками
Я написал функцию BirthdayAttribute, что хочу работать аналогично EmailAddressAttribute. Атрибут дня рождения устанавливает подсказку UI, чтобы день рождения DateTime отображался с использованием шаблона редактора, в котором есть три раскрывающихся списка. Атрибут также может быть использован для установки некоторых дополнительных метаданных, которые сообщают о выпадающем году, сколько лет оно должно отображаться.
Я знаю, что я мог бы использовать jQuery для выбора даты, но в случае дня рождения я нахожу, что 3 выпадающих меню гораздо удобнее.
@model DateTime
@using System;
@using System.Web.Mvc;
@{
UInt16 numberOfVisibleYears = 100;
if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("NumberOfVisibleYears"))
{
numberOfVisibleYears = Convert.ToUInt16(ViewData.ModelMetadata.AdditionalValues["NumberOfVisibleYears"]);
}
var now = DateTime.Now;
var years = Enumerable.Range(0, numberOfVisibleYears).Select(x => new SelectListItem { Value = (now.Year - x).ToString(), Text = (now.Year - x).ToString() });
var months = Enumerable.Range(1, 12).Select(x => new SelectListItem{ Text = new DateTime(now.Year, x, 1).ToString("MMMM"), Value = x.ToString() });
var days = Enumerable.Range(1, 31).Select(x => new SelectListItem { Value = x.ToString("00"), Text = x.ToString() });
}
@Html.DropDownList("Year", years, "<Year>")/
@Html.DropDownList("Month", months, "<Month>")/
@Html.DropDownList("Day", days, "<Day>")
У меня также есть ModelBinder для восстановления моей даты позже. Я сократил содержание моих вспомогательных функций для краткости, но все отлично работает до этого момента. Нормальные, правильные даты, отлично подходят для создания или редактирования моих участников.
public class DateSelector_DropdownListBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
if (IsDropdownListBound(bindingContext))
{
int year = GetData(bindingContext, "Year");
int month = GetData(bindingContext, "Month");
int day = GetData(bindingContext, "Day");
DateTime result;
if (!DateTime.TryParse(string.Format("{0}/{1}/{2}", year, month, day), out result))
{
//TODO: SOMETHING MORE USEFUL???
bindingContext.ModelState.AddModelError("", string.Format("Not a valid date."));
}
return result;
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
private int GetData(ModelBindingContext bindingContext, string propertyName)
{
// parse the int using the correct value provider
}
private bool IsDropdownListBound(ModelBindingContext bindingContext)
{
//check model meta data UI hint for above editor template
}
}
Теперь, когда я смотрю на него, я, вероятно, должен использовать нулевую дату DateTime, но это ни здесь, ни там.
Проблема, с которой я столкнулся, заключается в очень простой проверке недействительных дат, таких как 30 февраля или 31 сентября. Сама проверка достоверно работает, но недействительные даты никогда не сохраняются и сохраняются при перезагрузке формы.
Я хотел бы запомнить недействительную дату 30 февраля и повторно отобразить ее с помощью сообщения о проверке вместо сброса выпадающих списков до их значения по умолчанию. Другие поля, такие как адрес электронной почты (украшенный атрибутом EmailAddressAttribute), сохраняют недействительные записи только в порядке.
На данный момент я просто пытаюсь получить валидацию на стороне сервера. Честно говоря, я еще не начал думать о проверке на стороне клиента.
Я знаю, что есть много я мог бы сделать с Javascript и AJAX, чтобы сделать эту проблему спорным вопросом, но я бы все-таки предпочел бы надлежащее стороне сервера проверка на месте, чтобы возвратиться.
Если вы добавляете изменения в раскрывающееся меню, вы можете создать полную дату в скрытом поле и подтвердить это, вы можете повторно выбрать значения в раскрывающемся списке из значения скрытого текстового поля, однако это так и будет код на стороне клиента – davethecoder