0

I am trying to insert a new record into database, no errors, a new record is not created in Applicant and ApplicantNotification table. Not sure what I am doing wrong?

Applicant

  [Index]
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ApplicantID { get; set; }
    [Required]
    public string ApplicantTitle { get; set; }
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Lastname { get; set; }
    [Required]
    public string Address { get; set; }
    [Required]
    public string Address1 { get; set; }
    [Required]
    public string Address2 { get; set; }
    [Required]
    public string Address3 { get; set; }
    [Required]
    public string Postcode { get; set; }
    [Required]
    public string CaseReference { get; set; }
    [DataType(DataType.Date)]
    public DateTime DateOfBirth { get; set; }

    /*Spouse*/
    public string SpouseTitle { get; set; }
    public string SpouseFirstname { get; set; }
    public string SpouseLastname { get; set; }
    public string SpouseAddress { get; set; }
    public string SpouseAddress1 { get; set; }
    public string SpouseAddress2 { get; set; }
    public string SpouseAddress3 { get; set; }
    public string SpousePostcode { get; set; }

ApplicantNotification

        [Index]
        [Key, Column("ApplicantID"), ForeignKey("Applicant")]
        public int ApplicantNotificationID { get; set; }
        public bool FirstNotification { get; set; }
        public bool SecondtNotification { get; set; }
        public bool ThirdNotification { get; set; }
        public bool FinalNotification { get; set; }
        public DateTime ReminderDate { get; set; }
        public int ReminderFrequency { get; set; }
        [DataType(DataType.Date)]
        public DateTime? FirstNotificationDate { get; set; }
        [DataType(DataType.Date)]
        public DateTime? SecondNotificationDate { get; set; }
        [DataType(DataType.Date)]
        public DateTime? ThirdNotificationDate { get; set; }
        public bool IsArchive { get; set; }
        public virtual Applicant Applicant { get; set; }

ViewModel

        public int ApplicantID { get; set; }
        [Required]
        public string ApplicantTitle { get; set; }
        public string ApplicantFirstname { get; set; }
        public string ApplicantLastname { get; set; }
        public string ApplicantAddress { get; set; }
        public string ApplicantAddress1 { get; set; }
        public string ApplicantAddress2 { get; set; }
        public string ApplicantAddress3 { get; set; }
        public string ApplicantPostcode { get; set; }
        [Required]
        public string ApplicantCaseReference { get; set; }
        [Required]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime ApplicantDateOfBirth { get; set; }
        /*Spouse*/
        public string SpouseTitle { get; set; }
        public string SpouseFirstname { get; set; }
        public string SpouseLastname { get; set; }
        public string SpouseAddress { get; set; }
        public string SpouseAddress1 { get; set; }
        public string SpouseAddress2 { get; set; }
        public string SpouseAddress3 { get; set; }
        public string SpousePostcode { get; set; }
        /*Notification*/
        public int ApplicantNotificationID { get; set; }
        public bool FirstNotification { get; set; }
        public bool SecondNotification { get; set; }
        public bool ThirdNotification { get; set; }
        public bool FinalNotification { get; set; }
        public DateTime? ReminderDate { get; set; }

Create Method:

// POST: Applicant/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ApplicantNotificationViewModel model)
{
    var applicant = new Applicant();
    var applicantNotification = new ApplicantNotification();

        if (ModelState.IsValid)
        {
            SetApplicant(model, applicant);
            SetApplicantNotification(model, applicantNotification);

            using (var context = new WorkSmartContext())
            {
                using (var dbContextTransaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        db.Applicants.Add(applicant);
                        context.SaveChanges();
                        db.ApplicantNotifcations.Add(applicantNotification);
                        context.SaveChanges();
                        dbContextTransaction.Commit();
                    }
                    catch (Exception)
                    {
                        dbContextTransaction.Rollback();
                    }
                }

            return RedirectToAction("Index");
        }
    }
    return View(model);
}
Harry
  • 3,031
  • 7
  • 42
  • 67
  • why do you check model.isValid twice – hasan Jun 09 '17 at 22:56
  • 1
    No related, but your using a view model. Delete that awful `[Bind]` attribute –  Jun 09 '17 at 22:56
  • @hasan sorry that was a typo – Harry Jun 09 '17 at 22:58
  • my understanding was to have the Bind attribute there to stop from overposting? are you saying you don't need to specify it for a viewmodel?@StephenMuecke – Harry Jun 09 '17 at 22:59
  • If you have a view model, then no (your already protected against over-posting attacks because you only map what you want to the data model). And why are you creating the data models twice? - it can be just `db.Applicants.Add(applicant);` and `db.ApplicantNotifcations.Add(applicantNotification)` since you have already mapped the view models to instances of the data models –  Jun 09 '17 at 23:03
  • I tried db.Applicants.Add(applicant) and db.ApplicantNotifcations.Add(applicantNotification) but nothing gets added to the database. So i tried the above approach also. – Harry Jun 09 '17 at 23:05
  • Are you sure there is no exception - if its not being added it suggests your hitting the `catch` block. Have you put a breakpoint on it to check? –  Jun 09 '17 at 23:08
  • I have stepped through this, and I can confirm it does not hit the catch block. In fact, it reaches the dbContextTransaction.Commit(); that's why I am stumped, is there a way I could see the insert statement perhaps? – Harry Jun 09 '17 at 23:10
  • Also sees odd that you only have validation attributes on 2 properties. Surely properties such as `ApplicantFirstname` and `ApplicantLastname` would be required? –  Jun 09 '17 at 23:11
  • Yes you are right I agree and I will address that, however the issue I face is cannot insert data into database at the moment...When posting data, all the fields that map to the view model are filled in – Harry Jun 09 '17 at 23:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146308/discussion-between-stephen-muecke-and-haris). –  Jun 09 '17 at 23:14

1 Answers1

0

Thanks for the suggestions in the comments.

It appears, if the datetime column is set to allow null, then the datetime either has to be set to null or set to the correct format in order for sql datetime to work. Otherwise it throws the

"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\The statement has been terminated."

https://stackoverflow.com/questions/4608734/the-conversion-of-a-datetime2-data-type-to-a-datetime-data-type-resulted-in-an-o

I set the dates to null in my Entity objects, and entered a new entry to the database.

Harry
  • 3,031
  • 7
  • 42
  • 67