これは、ViewModelに1つのDateTimeプロパティしかないときに、日付を3つのフィールドに分割するために使用する手法です。正確にはあなたが求めているものではありませんが、あなたはあなたが望むものを達成するために同様の方法を使うことができるはずです。
エディターテンプレート
/views/shares/editortempaltes/datetime.cshtml
@model Nullable<System.DateTime>
@Html.TextBox("Day", Model.HasValue ? Model.Value.Day.ToString() : "", new { Type = "Number", @class="date-day" })
@Html.ValidationMessage("Day")
@Html.DropDownList("Month", months, new { @class="date-month" })
@Html.ValidationMessage("Month")
@Html.TextBox("Year", Model.HasValue ? Model.Value.Year.ToString() : "", new { Type = "Number", @class="date-year" })
@Html.ValidationMessage("Year")
カスタムModelBinder
public object GetValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
int day, month, year;
if (TryGetValue(controllerContext, bindingContext, propertyDescriptor.Name + ".Day", out day) && TryGetValue(controllerContext, bindingContext, propertyDescriptor.Name + ".Month", out month) && TryGetValue(controllerContext, bindingContext, propertyDescriptor.Name + ".Year", out year))
{
try
{
return new DateTime(year, month, day);
}
catch (ArgumentOutOfRangeException)
{
var fullPropertyName = bindingContext.ModelName + "." + propertyDescriptor.Name;
bindingContext.ModelState[fullPropertyName] = new ModelState();
bindingContext.ModelState[fullPropertyName].Errors.Add("Invalid date");
}
}
return null;
}
private bool TryGetValue(ControllerContext controllerContext, ModelBindingContext bindingContext, string propertyName, out int value)
{
var fullPropertyName = bindingContext.ModelName + "." + propertyName;
string stringValue = controllerContext.HttpContext.Request[fullPropertyName];
bindingContext.ModelState.Add(fullPropertyName, new ModelState() { Value = new ValueProviderResult(stringValue, stringValue, null) });
return int.TryParse(stringValue, out value);
}
使用法
ViewModelにDateTimeプロパティを追加してから、
@Html.EditorFor(m => m.DateTimeProperty)