In our ASP MVC 3 site, we want the user to be able to enter an incomplete form, save that record to the database, and come back to the form later. If there were fields entered incorrectly we want those error message to appear when the user hits save.
A problem is occurring specific to the date of birth field, however. If a user enters an incorrect date such as 14/01/2011, when the user hits save and the model object POSTs back to the controller action, the date of birth comes through as blank. It then fails the if (ModelState.IsValid) condition, does not save to the database, and is sent back to the view with a blank date of birth.
Is there a way to allow the user to enter an incorrect date in this field, keep that value and POST back to the view with that value and the error message that would normally be generated by the model? Since we are using a jQuery input mask, the value entered will always be numeric and in MM/DD/YYYY format.
Model
[DisplayName("Date of Birth")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? Birthdate { get; set; }
Controller
[HttpPost]
public ActionResult Edit(Monet.Models.AgentTransmission agenttransmission)
{
//Date of birth field is null right here in 'agenttransmission' object if
//user enters incorrect value/date
//redirect if security is not met.
if (!Security.IsModifier(User)) return RedirectToAction("Message", "Home", new { id = 1 });
//Tax Id security
ViewBag.FullSSN = Security.IsFullSsn(User);
try
{
agenttransmission = AgentTransmissionValidator.ReformatFields(agenttransmission);
ViewBag.ErrorMessage = AgentTransmissionValidator.ValidateAgent(agenttransmission);
if (ModelState.IsValid)
{
//Whole bunch of code to determine if input is complete/incomplete
//Save the record
db.Entry(agenttransmission).State = EntityState.Modified;
db.SaveChanges();
} //end if model state valid
}
catch (DbEntityValidationException dbEx)
{
ViewBag.ErrorMessage = "An error has occurred, we apologize for the incovenience. IT has been notified and will resolve the issue shortly.";
SendEmail.ErrorMail(Common.ErrorCheck.CombineDbErrors(dbEx));
}
catch (Exception ex)
{
ViewBag.ErrorMessage = ErrorCheck.FriendlyError(ex);
SendEmail.ErrorMail(ex);
}
return View(agenttransmission);
}
View
<div class="M-editor-label">
@Html.LabelFor(model => model.Birthdate)<span class="req">*</span>
</div>
<div class="M-editor-field">
@Html.EditorFor(model => model.Birthdate)
@Html.ValidationMessageFor(model => model.Birthdate)
</div>
As Queti Mporta suggested, the problem is that, when you post back, the model binder tries to parse "14/01/2011" into a DateTime? and fails, so it uses the default value instead. For a nullable type, the default is null, which is why you get a blank.
If you were to change your model to...
[DisplayName("Date of Birth")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public string Birthdate { get; set; } // note: string instead of DateTime?
...the user can now enter anything with the format MM/dd/yyyy, but when it is posted back, it will just be stored in a string.
You will now need to add logic (in your controller or somewhere accessible from your controller) to attempt a parse yourself:
DateTime birthdate;
var isDateValid = DateTime.TryParse(agenttransmission.Birthdate, out birthday);
if (!isDateValid ) ModelState.AddModelError("Birthdate", "Birthday needs to be a valid date.");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With