Set property combining 3 MVC dropdowns

I am trying to set the DateTime property Birthday

for a date of birth using 3 dropwdowns for month, day and year in MVC. At the moment, I cannot get a valid ModelState. In addition, the values โ€‹โ€‹of `model.Birthday. [Month, Day or Year] is not recognized from the mark. Please, help.

My markup looks like this:

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

      

My ViewModel looks like this:

public class RegisterModel
{
   ...    

   [DataType(DataType.Date)]
   [Display(Name = "Birthday")]
   public DateTime Birthday { get; set; }
}

      

My account looks like this:

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

      

+3


source to share


1 answer


You can create HTML helpers for properties with public setters in the model - not for things derived from properties in the model. Since Ric Notes - DateTime.Year / .Month / .Day properties are readonly and therefore cannot be linked.

What you need to do is create a new view model:

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

      

If you want to perform validation to make sure the date is valid (i.e. to ensure that they cannot pick the 29th month during a non-leap year, etc.), you will need a special validation attribute - this article looks like pretty good: http://dotnetspeak.com/2012/05/validating-dependent-fields-in-asp-net-mvc



An easier approach if you only need server side validation is to implement IValidateableObject

in your model class - eg: http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first -and-asp-net-mvc-3

As an alternative approach - you can just have one date field - but add a client side date picker - jQuery UI . well. (HTML5 <input type="Date">

is another approach, but you cannot guarantee that all of its clients support it)

One of the last options is to use a property <input type="hidden">

for the Date of Birth property , and on the client side javascript is tied to dropdowns which updates the hidden field when each dropdown changes.

+2


source







All Articles