mosh-hamedani / vidly-mvc-5

955 stars 1.53k forks source link

Can't add new customer after validation #192

Open MisterJay1 opened 3 years ago

MisterJay1 commented 3 years ago

After adding the validation for the Save action in the Customer's controller and adding the validation annotations in the CustomerForm.cshtml, I cannot add a new client.

This is the code for my Customer model (Customer.cs):

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace Vidly.Models
{
    public class Customer
    {
        public int Id { get; set; }

        [Required]
        [StringLength(255)]
        public string Name { get; set; }

        public bool IsSubscribedToNewsletter { get; set; }

        [Required]
        public MembershipType MembershipType { get; set; }

        [Display (Name = "Membership Type")]
        public byte MembershipTypeId { get; set; }

        [Display(Name = "Date of birth")]
        [Min18YearsIfAMember]
        public DateTime? Birthdate { get; set; }
    }
}

This the code for my MembershipType.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace Vidly.Models
{
    public class MembershipType
    {
        public byte Id { get; set; }

        public short SignUpFee { get; set; }

        public byte DurationInMonths { get; set; }

        public byte DiscountRate { get; set; }
        //[Required]
        public string Name { get; set; }

        public static readonly byte Unknown = 0;
        public static readonly byte PayAsYouGo = 1;
    }
}

This is the code for my CustomersController's Save Action:

[HttpPost]
        public ActionResult Save(CustomerFormViewModel viewModel)
        {
            if (!ModelState.IsValid)
            {
                var newViewModel = new CustomerFormViewModel()
                {
                    Customer = viewModel.Customer,
                    MembershipTypes = _context.MembershipTypes.ToList()
                };

                foreach (ModelState modelState in ViewData.ModelState.Values)
                {
                    foreach (ModelError error in modelState.Errors)
                    {
                        Console.WriteLine(error.ToString());
                    }
                }

                return View("CustomerForm", newViewModel);
            }

            if (viewModel.Customer.Id == 0)
                _context.Customers.Add(viewModel.Customer);
            else
            {
                var customerInDbo = _context.Customers.Single(c => c.Id == viewModel.Customer.Id);

                customerInDbo.Name = viewModel.Customer.Name;
                customerInDbo.Birthdate = viewModel.Customer.Birthdate;
                customerInDbo.MembershipTypeId = viewModel.Customer.MembershipTypeId;
                customerInDbo.IsSubscribedToNewsletter = viewModel.Customer.IsSubscribedToNewsletter;
            }

            _context.SaveChanges();

            return RedirectToAction("Index","Customers");
        }

This is the code for my CustomerForm.cshtml:

@model Vidly.ViewModels.CustomerFormViewModel
@{
    ViewBag.Title = "New";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>New Customer</h2>

@using (Html.BeginForm("Save", "Customers"))
{
    @Html.ValidationSummary()
    <div class="form-group">
        @Html.LabelFor(m => m.Customer.Name)
        @Html.TextBoxFor(m => m.Customer.Name, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Customer.Name)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Customer.Birthdate)
        @Html.TextBoxFor(m => m.Customer.Birthdate,new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Customer.Birthdate)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Customer.MembershipTypeId)
        @Html.DropDownListFor(m => m.Customer.MembershipTypeId, new SelectList(Model.MembershipTypes, "Id", "Name"), "Select Membership Type", new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Customer.MembershipTypeId)
    </div>
    <div class="checkbox">
        <label>
            @Html.CheckBoxFor(m => m.Customer.IsSubscribedToNewsletter) Is subscribed to newsletter?
        </label>
    </div>
    @Html.HiddenFor(m => m.Customer.Id)
    <button type="submit" class="btn btn-primary">Save</button>    
}

Whenever I go to http://localhost:58839/Customers/New and insert a new customer, after pressing save, I get the same page, basically the code goes in CustomersController's Save at return View("CustomerForm", newViewModel),

After going with the debug messages (foreach (ModelError error in modelState.Errors)) I found out that the problem is the fact that the Customer's that's being passed to the Save action by the CustomerForm.cshtml does not have an Id and a MembershipType. How can I solve this issue?

Bruno2012048 commented 3 years ago

I had same problem, the problem was in Index pages. ( View->Customers->Index.cshtml and View->Movies->Index.cshtml )

Bruno2012048 commented 3 years ago

image_2021-09-15_232105