ASP.NET mvc 2 - 将出生日期与下拉列表绑定

Chr*_*ris 9 asp.net-mvc-2

在ASP.NET MVC 2中,您将如何绑定视图模型属性,该属性是DateTime,其中应用程序必须具有3个下拉列表以选择月,日,年?我已阅读Scott H.的博客文章一段时间以前的约束日期,这对于这样一个简单的案例来说似乎完全过于复杂.当然有更干净/更好的方法吗?

无论我使用什么解决方案,我都希望使用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);
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试创建一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许我在我的视图模型上使用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; }
Run Code Online (Sandbox Code Playgroud)

但实际上,整个解决方案都有过度工程和过度思考的气味.有没有更好的方法?

swa*_*eel 1

创建单独的 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

    }
}
Run Code Online (Sandbox Code Playgroud)

在 post 方法中,您可以将用户选择的值分配给模型 BirthDate

出生日期.日期.AddDays(出生日期-1).AddMonths(出生日期月份)