0

I am using codefirst approach and entity framework to update my Customer by changing the name but EnityValidation Error occurs.As I try to debug it using trycatch block it shows the name field is required.

Error message while debugging

I used data annotation while using entity framework to my model class.

public class Customer
{
    public int Id { get; set; }

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

    [Display(Name ="Date Of Birth")]
    [DisplayFormat(ApplyFormatInEditMode =true,DataFormatString ="{0:dd/MM/yyyy}")]
    public DateTime? Birthdate { get; set; }

    public bool IsSubscribedToNewsletter { get; set; }

    public MembershipType MembershipType { get; set; }

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

[Action-Save in CustomersController]

[HttpPost]
    public ActionResult Save(Customer customer)
    {
        if (customer.Id == 0)
            _context.Customers.Add(customer);
        else
        {
            var customerInDb = _context.Customers.Single(c => c.Id == customer.Id);
            customerInDb.Name = customer.Name;
            customerInDb.Birthdate = customer.Birthdate;
            customerInDb.IsSubscribedToNewsletter = customer.IsSubscribedToNewsletter;
            customerInDb.MembershipTypeId = customer.MembershipTypeId;
        }
        try
        {
            _context.SaveChanges();
        }   
        catch (DbEntityValidationException e)
        {
            Console.WriteLine(e);
        }
        return RedirectToAction("Index", "Customers");
    }

[Edit-Action in CustomerController]

public ActionResult Edit(int id)
    {
        var customer = _context.Customers.SingleOrDefault(c => c.Id == id);

        if (customer == null)
        {
            return HttpNotFound();
        }

        var viewModel = new CustomerFormViewModel
        {
            Customers = customer,
            MembershipTypes = _context.MembershipType.ToList()
        };
        return View("CustomerForm", viewModel);
    }

[New-Action CustomerController]

public ActionResult New()
    {
        var membershipType = _context.MembershipType.ToList();

        var viewModel = new CustomerFormViewModel
        {
            MembershipTypes = membershipType
        };
        return View("CustomerForm", viewModel);

    }

[CustomerFormViewModel -CustomerController]

 public class CustomerFormViewModel
{
    public IEnumerable<MembershipType> MembershipTypes { get; set; }
    public Customer Customers { get; set; }
}

View-CustomerForm

@using (Html.BeginForm("Save","Customers"))
{
    <div class="form-group">
        @Html.LabelFor(c => c.Customers.Name)
        @Html.TextBoxFor(c => c.Customers.Name,new{ @class="form-control"})
    </div>
    <div class="form-group">
        @Html.LabelFor(c => c.Customers.Birthdate)
        @Html.TextBoxFor(c => c.Customers.Birthdate,"{0:d MMM yyyy}" ,new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(c => c.Customers.MembershipTypeId)
        @Html.DropDownListFor(c => c.Customers.MembershipTypeId,new SelectList(Model.MembershipTypes,"Id","Name"),"Select MembershipType",new { @class = "form-control" })
    </div>
    <div class="form-check">
        <label>
            @Html.CheckBoxFor(c => c.Customers.IsSubscribedToNewsletter) Subscribed To NewsLetter?
        </label>
    </div>
    @Html.HiddenFor(c => c.Customers.Id)
    <button type="submit" class="btn btn-primary">Save</button>

But this code works for another parameter "Movies".The movie object get passed.

[movies-model]

public class Movie
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Genre Genre { get; set; }
    public byte GenreId { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/mm/yyyy}")]
    public DateTime ReleaseDate { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/mm/yyyy}")]
    public DateTime DateAdded { get; set; }

    public byte NumberInStock { get; set; }
}

[Edit-Action MovieController]

public ActionResult Edit(int id)
    {
        var movie = _context.Movies.SingleOrDefault(m => m.Id == id);

        if (movie == null)
        {
            return HttpNotFound();
        }

        var viewModel = new MovieFormViewModel
        {
            Movie = movie,
            Genres = _context.Genre.ToList()
        };
        return View("MovieForm",viewModel);
    }

[New-Action MovieController]

public ActionResult New()
    {
        var genre = _context.Genre.ToList();

        var viewModel = new MovieFormViewModel()
        {
            Genres = genre
        };
        return View("MovieForm", viewModel);
    }

[Save-Action MovieController]

[HttpPost]
    public ActionResult Save(Movie movie)
    {
        if(movie.Id==0)
        {
            movie.DateAdded = DateTime.Now;
            _context.Movies.Add(movie);
        }
        else
        {
            var movieInDb = _context.Movies.SingleOrDefault(m => m.Id == movie.Id);
            movieInDb.Name = movie.Name;
            movieInDb.NumberInStock = movie.NumberInStock;
            movieInDb.GenreId = movie.GenreId;
            movieInDb.ReleaseDate = movie.ReleaseDate;
        }

        _context.SaveChanges();

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

[MovieFormviewModel]

public class MovieFormViewModel
{
    public Movie Movie { get; set; }
    public IEnumerable<Genre> Genres { get; set; }

    public string Title
    {
        get
        {
            if(Movie != null && Movie.Id !=0)
            {
                return "Edit Movie";
            }
            else
            {
                return "New Movie";
            }
        }

    }
}

[movieForm-View]

@model Vidly.ViewModels.MovieFormViewModel

@{
    ViewBag.Title = Model.Title;
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>New Movie</h2>

@using (Html.BeginForm("Save", "Movies"))
{
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.Name)
        @Html.TextBoxFor(m => m.Movie.Name,new { @class="form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.ReleaseDate)
        @Html.TextBoxFor(m => m.Movie.ReleaseDate, new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.GenreId)
        @Html.DropDownListFor(m => m.Movie.GenreId,new SelectList(Model.Genres,"Id","Name"),"Select Genre", new { @class = "form-control"})
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.NumberInStock)
        @Html.TextBoxFor(m => m.Movie.NumberInStock, new { @class = "form-control" })
    </div>
    @Html.HiddenFor(m => m.Movie.Id)
    <button type="submit" class="btn btn-primary">Save</button>
}

**How can i remove this error?Why is the object not getting passed for customers but for movies!!Both are basically same! **

  • For a start you are creating form controls for a model which is not `Customer` so it will never bind to `Customer` in the POST method –  Apr 04 '18 at 11:27
  • I am on the process of learning code-first migrations and mvc5. I am a beginner. Can you please tell me how I can remove this error? –  Apr 04 '18 at 11:28
  • 1
    No one is going to help you until you post the code as code in your question (not links to images) –  Apr 04 '18 at 11:43
  • I have posted the code –  Apr 04 '18 at 11:54
  • 1
    You have not shown the view (and if your bother to debug your code, you will see that all the the properties of `customer` are their defaults - but I previously explained why that is - the model in the view and the model in the post method need to be the same) –  Apr 04 '18 at 11:56
  • 3
    And because you are editing data you ALWAYS use a [view model](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc), NEVER your data model –  Apr 04 '18 at 11:57
  • 1
    No, do not remove it from your entity. Create a ViewModel with a Name and make that [Required] too. – H H Apr 04 '18 at 12:10
  • I'm almost sure that your `Customer` parameter is null when is entering to the `Save` method. So, you have to review how you're sending the `Customer`object – JPocoata Apr 04 '18 at 21:36
  • the exception tells you why it occurs, and you see in your code that it is indeed required. Since you go code first, I don't quite see how we could explain to you how to remove one line of code. – DevilSuichiro Apr 05 '18 at 08:52
  • for editing I have used a viewModel not the datamodel. I have assigned the customer entities to a local variable "customerinDb" and used it to save to database. but the customer parameter is going null when trying to save/edit it. I have used almost the same code/logic for another parameter which is "movies" and it works.The customer object is not getting passed.Or am i wrong? @StephenMuecke –  Apr 17 '18 at 07:23
  • I used a customer object and used it to assign the customer variables to another local variable "customerInDb" and used it to save the dbset. No idea why the customer object is not getting passed. I am learning,The same logic works perfectly for another parameter "Movies"(Basically the same code).@JesusPocoata –  Apr 17 '18 at 07:27
  • @joe17. I cant see your new code :) Ask a new question with the code you have tried and explain what you expect to happen, and what is actually happening –  Apr 17 '18 at 07:42
  • I have added the parameter "Movie" @StephenMuecke –  Apr 17 '18 at 08:12
  • That is not a view model. View models do not contain data models. That contain the properties of your data model that you need/edit in the view. [What is ViewModel in MVC?](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Apr 17 '18 at 08:15
  • And the model in your POST method needs to be the same model as you have used in the view. –  Apr 17 '18 at 08:16

0 Answers0