In my view MoviesForm.cshtml there is a BeginForm which I am trying to use to pass a model to an action called Save in the Movies controller. However, when debugging, I noticed that this model passed to the Save action is always null and I am just not sure why.
Here is the model class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace vidly.Models
{
public class Movies
{
public Movies()
{
DateAdded = DateTime.Now;
}
public int Id { get; set; }
public string Name { get; set; }
[Display(Name = "Number in Stock")]
public int Availability { get; set; }
[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }
public DateTime DateAdded { get; set; }
public Genre Genre { get; set; }
[Display(Name = "Genre")]
[Required]
public int GenreId { get; set; }
}
}
Here is my action in the controller
[HttpPost]
public ActionResult Save(Movies movies)
{
System.Diagnostics.Debug.WriteLine($"Object: {movies.Name} {movies.Id}");
if (movies.Id == 0)
{
movies.DateAdded = DateTime.Now;
_context.Movies.Add(movies);
}
else
{
var selectedMovie = _context.Movies.Single(c => c.Id == movies.Id);
selectedMovie.Name = movies.Name;
selectedMovie.ReleaseDate = movies.ReleaseDate;
selectedMovie.GenreId = movies.GenreId;
selectedMovie.Availability = movies.Availability;
}
_context.SaveChanges();
return RedirectToAction("Index", "Movies");
}
And here is the view
@model vidly.ViewModel.MoviesFormViewModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>@ViewBag.Save - 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, "{0:d MMM yyyy}", new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Movie.GenreId)
@Html.DropDownListFor(m => m.Movie.GenreId, new SelectList(Model.Genre, "Id", "Name"), "Select a Genre", new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Movie.Availability)
@Html.TextBoxFor(m => m.Movie.Availability, new { @class = "form-control" })
</div>
@Html.HiddenFor(m => m.Movie.Id)
<button type="submit" class="btn btn-primary">Save</button>
}
Thanks!
Your ViewModel is a
MoviesFormViewModel. When you use the extensions to build things like@Html.TextBoxFor(m => m.Movie.Name, the generated html (which you should take a look at) is going to expect an object that has aMovieobject as a property on it.But your controller is expecting a
Moviesobject directly. So the framework's ModeBinder is going to get hung up on building your model and trying to figure out how to map the properties, because they are not the same object.You can change the controller action to accept a
MoviesFormViewModel, then access theMovieproperty on that, or you can manually build your inputs to match theMoviesobject the action is expecting.