在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)
但实际上,整个解决方案都有过度工程和过度思考的气味.有没有更好的方法?
创建单独的 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(出生日期月份)