我尝试使用MVC中的月,日和年3次下线来为出生日期设置DateTime属性Birthday
。此时我无法获得有效的ModelState。此外,`model.Birthday。[月,日或年]'标记中未识别出值。请帮忙。
我的标记如下:
@model StatisticalTracker.Models.RegisterModel
...
<li>
@Html.LabelFor(m => m.Birthday)
@Html.DropDownListFor(m => m.Birthday.Month, SelectListItemHelper.GetMonths(), "-- Month --", new { style = "display: inline-block" }) /
@Html.DropDownListFor(m => m.Birthday.Day, SelectListItemHelper.GetDays(), "-- Day --", new { style = "display: inline-block" }) /
@Html.DropDownListFor(m => m.Birthday.Year, SelectListItemHelper.GetYears(), "-- Year --", new { style = "display: inline-block" })
</li>
我的ViewModel如下:
public class RegisterModel
{
...
[DataType(DataType.Date)]
[Display(Name = "Birthday")]
public DateTime Birthday { get; set; }
}
我的控制者如下:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (model.Birthday.Month == 0 || model.Birthday.Day == 0 && model.Birthday.Year == 0)
{
ModelState.AddModelError("Birthday", "Date of birth is required");
}
else
{
DateTime dt = new DateTime(model.Birthday.Year, model.Birthday.Month, model.Birthday.Day);
model.Birthday = dt;
}
if (ModelState.IsValid)
{
...
}
// If we got this far, something failed, redisplay form
return View(model);
}
答案 0 :(得分:2)
您可以为模型中具有公共设置器的属性创建HTML帮助程序 - 而不是为从模型中的属性派生的内容创建HTML帮助程序。作为Ric Notes - DateTime.Year / .Month /.Day属性是只读的,因此无法绑定。
您应该做的是创建一个新的视图模型,如:
public class RegisterModel
{
...
[Display(Name = "Birthday Year")]
public int BirthdayYear { get; set; }
[Display(Name = "Birthday Month")]
public int BirthdayMonth { get; set; }
[Display(Name = "Birthday Day")]
public int BirthdayDay { get; set; }
}
如果您想要实施验证以确保日期有效(即确保他们无法在非闰年中选择29个星期等),您将需要自定义验证属性 - 这篇文章看起来很漂亮好的:http://dotnetspeak.com/2012/05/validating-dependent-fields-in-asp-net-mvc
如果您只需要服务器端验证,则更简单的方法是在模型类中实现IValidateableObject
- 例如:http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3
作为替代方法 - 你可以只有一个日期字段 - 但添加一个客户端日期选择器 - jQuery UI一个非常好。 (HTML5 <input type="Date">
是另一种方法,但您不能保证所有客户都支持它)
最后一个选项是使用<input type="hidden">
作为生日日期属性,并将一些客户端javascript绑定到下拉列表,以便在每个下拉列表更改时更新隐藏字段。