Reputation: 2527
I have Add and Edit actions in my MovieController that both go to the MovieForm View. Within the MovieForm view, I have the following:
@Html.TextBoxFor(m => m.Movie.ReleaseDate, "{0:MMM dd yyyy}", new { @class = "form-control" })
Also see my corresponding Movie model:
public class Movie
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
public Genre Genre { get; set; }
[Required]
[Display(Name = "Genre")]
public byte GenreId { get; set; }
[Display(Name ="Release Date")]
public DateTime ReleaseDate { get; set; }
public DateTime DateAdded { get; set; }
[Display(Name = "Number in Stock")]
public int NumberInStock { get; set; }
}
And ViewModel:
public class MovieFormViewModel
{
public IEnumerable<Genre> Genres { get; set; }
public Movie Movie { get; set; }
public bool IsNew { get; set; }
}
}
So as you can see, there doesn't appear to be anything wrong with the ReleaseDate property. In the database (localDB) it is of type "datetime".
However, what's strange is that whenever I edit a movie and change the release date, everything is fine. However, if I ADD a movie (even though its the same MovieForm), I get this Exception:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated.
I've tried stepping through it all and trying a try catch but that above error is the only thing I can extract out of what is going on. It just makes no sense to me that I can edit and successfully write to the database using the exact same form and exact same Save() action but for some reason, when it comes to creating a new entry, it's not working. It'll even work if I enter the date exactly the same way directly into the DB.
I've also seen this question however it is not addressing the issue that I'm having. I'll even provide both my actions here so you can see them:
public ActionResult Edit(int id)
{
var movie = _context.Movies.SingleOrDefault(m => m.Id == id);
//Make sure that the id actually exists:
if (movie == null)
{
return HttpNotFound();
}
var viewModel = new MovieFormViewModel
{
Movie = movie,
IsNew = false,
Genres = _context.Genres.ToList()
};
return View("MovieForm", viewModel);
}
public ActionResult Save(Movie movie)
{
if (movie.Id == 0)
{
_context.Movies.Add(movie);
}
else
{
//This method of data entry allows you to explicitly control which items in the Db can be updated by the user. More secured than an update-all method like TryUpdateModel()
var movieInDb = _context.Movies.Single(c => c.Id == movie.Id);
movieInDb.ReleaseDate = movie.ReleaseDate;
movieInDb.Name = movie.Name;
movieInDb.Genre = movie.Genre;
movieInDb.NumberInStock = movie.NumberInStock;
movieInDb.DateAdded = DateTime.Today.Date;
}
_context.SaveChanges();
return RedirectToAction("Index", "Movies");
}
public ActionResult New()
{
var genres = _context.Genres.ToList();
var viewModel = new MovieFormViewModel
{
Genres = genres,
IsNew = true
};
return View("MovieForm", viewModel);
}
Note that the exception is occurring on the _context.SaveChanges() method. Also note that I've tried removing the movieInDb.DateAdded = DateTime.Today.Date; but that doesn't have anything to do with it as I added it after I was experiencing this exception with the ReleaseDate. I also tried playing with the DateTime formatting of the ReleaseDate which didn't help either.
Upvotes: 1
Views: 1133
Reputation: 2527
In the Save() Action in the MovieController, look carefully at the if statement. Since the exception was happening only when a NEW movie was being added, this means that there was a problem in the case that movie.Id == 0 (new movie). The problem was that the movie.DateAdded property was not being set by the form, thus it was never being set at all. This was causing movie.DateAdded to be null and thus throwing the exception. The fix - set movie.DateAdded equal to the current date before the commit to the database like so:
if (movie.Id == 0)
{
movie.DateAdded = DateTime.Now;
_context.Movies.Add(movie);
}
Upvotes: 3