ASP.NET MVC 2 - привязка даты рождения с выпадающими - PullRequest
9 голосов
/ 07 сентября 2010

Как в ASP.NET MVC 2 связать свойство модели представления, представляющее собой DateTime, где у приложения должно быть 3 раскрывающихся списка для выбора месяца, дня и года? Я читал Скотта Х. сообщение в блоге об обязательных датах некоторое время назад, и это кажется слишком запутанным для такого простого случая. Конечно, есть более чистый / лучший способ сделать это?

Какое бы решение я ни использовал, я бы хотел сохранить встроенную проверку с использованием материала DataAnnotations, а также хотел бы иметь возможность указать минимальный / максимальный диапазон дат с помощью атрибута проверки.

Моей первой мыслью было простое пользовательское связующее для модели:

protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
    var model = bindingContext.Model as RsvpViewModel;
    var form = controllerContext.HttpContext.Request.Form;

    if (model == null) 
        throw new ArgumentException("bindingContext.Model");

    if (propertyDescriptor.Name.Equals("BirthDate"))
    {
        if (!string.IsNullOrEmpty(form["BirthYear"]) &&
            !string.IsNullOrEmpty(form["BirthMonth"]) &&
            !string.IsNullOrEmpty(form["BirthDay"]))
        {
            try
            {
                var yy = int.Parse(form["BirthYear"]);
                var mm = int.Parse(form["BirthMonth"]);
                var dd = int.Parse(form["BirthDay"]);
                model.BirthDate = new DateTime(yy, mm, dd);
                return;
            }
            catch (Exception)
            {
                model.BirthDate = DateTime.MinValue;
                return;
            }
        }
    }

    base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}

Затем я попытался создать атрибут DateTimeAttribute для проверки, но столкнулся с некоторыми трудностями при указании диапазона дат в объявлении атрибута, поскольку типы параметров атрибута ограничены, а DateTime не является одним из допустимых типов.

Я закончил тем, что создал интерфейс IDateRangeProvider и реализацию, специфичную для дат рождения, например:

public interface IDateRangeProvider
{
    DateTime GetMin();
    DateTime GetMax();
}

public class BirthDateRangeProvider : IDateRangeProvider
{
    public DateTime GetMin()
    {
        return DateTime.Now.Date.AddYears(-100);
    }

    public DateTime GetMax()
    {
        return DateTime.Now.Date;
    }
}

Это позволило мне использовать свойство DateTime в моей модели представления и сохранить все сборки в совершенстве ...

[DisplayName("Date of Birth:")]
[Required(ErrorMessage = "Date of birth is required")]
[DateTime(ErrorMessage = "Date of birth is invalid", RangeProvider=typeof(BirthDateRangeProvider))]
public DateTime? BirthDate { get; set; }

Но на самом деле весь раствор пахнет чрезмерной инженерией и переосмыслением. Разве нет лучшего способа?

Ответы [ 3 ]

1 голос
/ 31 марта 2011

создать отдельный выпадающий список 3 и добавить для них обязательный атрибут проверки.

и использовать BdateList, BMonthList для заполнения вашего DropdownList

[DisplayName("Date of Birth ")]
public DateTime? Birthdate { get; set; }

[Required(ErrorMessage = "Date is required")]
public int BirthDateDate { get; set; }
[Required(ErrorMessage = "Month is required")]
public int BirthDateMonth { get; set; }
[Required(ErrorMessage = "Year is required")]
public int BirthDateYear { get; set; }


public List<System.Web.Mvc.SelectList> BDateList
{
    get
    {
        // create List here

    }
}

и вметодом post вы можете назначить значения, выбранные пользователем, для модели BirthDate

BirthDate.Date.AddDays (BirthDateDate -1) .AddMonths (BirthDateMonth)

0 голосов
/ 13 ноября 2012

вы можете иметь пользовательский тип для дня рождения, который будет иметь свойства, такие как

public class BirthDateModel
{
    [Required(), Range(1, 12)]
    public Int32 BirthMonth { get; set; }

    [Required, Range(1, 31)]
    [DayShouldBeValid("BirthYear", "BirthMonth")]
    public Int32 BirthDay { get; set; }

    [Required,Range(1990, 2012)]
    public virtual Int32 BirthYear { get; set; }

    public DateTimeOffset GetBirthDate()
    {
        DateTimeOffset birthDate;
        if (DateTimeOffset.TryParse(String.Format("{0}-{1}-{2}", BirthMonth, BirthDay, BirthYear), out birthDate))
            return birthDate;

        // what should be returned here?
        return DateTime.MinValue;
    }

}

Теперь создайте пользовательский валидатор aka DayShouldBeValid, чтобы проверить месяц и год, действительный день или нет.

Не каждая часть даты имеет свой собственный контроль.

0 голосов
/ 30 апреля 2011

идея для вас

теперь в вашей сущности есть класс birthDate

public class birthDate{
public int day{get;set;}
public int month{get;set;}
public int year{get;set;}
}

: установите для элемента даты рождения значение private

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...