在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);
}
然后我尝试创建一个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; }
但实际上,整个解决方案都有过度工程和过度思考的气味。是不是有更好的方法?
答案 0 :(得分:1)
创建seprate 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方法中你可以分配 用户选择的值为Model BirthDate
BirthDate.Date.AddDays(BirthDateDate -1).AddMonths(BirthDateMonth)
答案 1 :(得分:0)
给你一个想法
有class birthDate
public class birthDate{
public int day{get;set;}
public int month{get;set;}
public int year{get;set;}
}
现在在您的实体中: 将您的生日元素设置为私有
并将出生日期项目添加到课程中 在你只是处理每个部分的项目后。 并将此处理为一个日期:)
答案 2 :(得分:0)
您可以拥有生日的自定义类型,其中包含
等属性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来检查月份和年份,这一天是否有效。
并非日期的每个部分都有自己的控制权。