Reputation: 1
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!
Upvotes: 0
Views: 232
Reputation: 1
Thank you!! It worked, I changed the parameter from the Save action to MovieFormViewModel, I actually though about doing something like that, but I got another controller which works exactly the same way as I was previously trying, so I didn't do it.
Upvotes: 0
Reputation: 25370
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 a Movie
object as a property on it.
But your controller is expecting a Movies
object 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 the Movie
property on that, or you can manually build your inputs to match the Movies
object the action is expecting.
Upvotes: 2