2014-12-23 2 views
3

Я пытаюсь установить свойство DateTime Birthday для даты рождения, используя 3 dropwdowns для месяца, дня и года в MVC. На данный момент я не могу получить действительный ModelState. Кроме того, значения `model.Birthday. [Месяц, День или Год] не распознаются с отметки. Пожалуйста помоги.Установить свойство, объединяющее 3 выпадающих списка MVC

Моя разметка выглядит следующим образом:

@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; } 
} 

Мой Conroller выглядит следующим образом:

[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); 
} 

ответ

2

Вы можете создать HTML Помощники для свойств с публичными установщиками в модели - не для вещей, полученных из свойств в модели. Поскольку Ric Notes - свойства DateTime.Year/.Month /.Day являются readonly и, следовательно, не могут быть связаны.

Что вы должны сделать, это создать новый ViewModel как:

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 один довольно хорош. (The HTML5 <input type="Date"> другой подход, но вы не можете гарантировать, что все клиент поддерживают)

Один окончательного варианта заключается в использовании <input type="hidden"> для свойства Birthday Даты и есть сторона клиента Javascript связанного с выпадающими, какими обновлениями скрытое поле при изменении каждого из выпадающих меню.

+0

Я пытался избежать необходимости сохранять 3 separtate поля БД и объединить их в один, но я попробую, если это самый простой способ – MTL323

+0

Вам не нужно хранить эти поля отдельно в базе данных - модель может быть класс, который вы создаете именно для этого представления. конвертируйте его перед сохранением в базу данных. –

+0

Я тоже собирался опубликовать этот ответ. У вас должны быть свойства, у которых есть сеттеры. Похоже, что 'DateTime.Day' является readonly и не может быть назначен. Этот ответ решает эту проблему. – Ric

Смежные вопросы