My MVC5 project View makes an api call to api/movies where the following logic exists:
(First, this is how the moviesDto is instantiated):
var moviesQuery = _context.Movies.Include(m => m.Genre);
var moviesDto = moviesQuery.ToList()
.Select(Mapper.Map<Movie, MovieDto>);
And here's the logic:
//for regular API call add N/A to items that are not available
foreach (MovieDto movie in moviesDto)
{
if (movie.NumberAvailable == 0)
movie.Name = movie.Name + " N/A. :(";
}
return Ok(moviesDto);
I inspect the movie object(s) at run-time IN THE Foreach LOOP in debug mode and indeed find that the name property for some movies has "N/A :(" appended to it. But in the view, only the movie's (original) name appears.
Edit: On inspection of the moviesDto on the last line above line just before it is returned to caller, I find that the relevant movies' names have not been updated.
FWIW, This is the movieDto class definition:
public class MovieDto
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
public byte GenreId { get; set; }
public GenreDto Genre { get; set; }
public DateTime ReleaseDate { get; set; }
public DateTime DateAdded { get; set; }
[Range(1, 25)]
public byte NumberInStock { get; set; }
public byte NumberAvailable { get; set; }
}
Your issue arises from the use of an IEnumerable
(due to LINQ deferred execution ) and is caused by the fact that your moviesDto
object is effectively a LINQ query.
Each time moviesDto
is enumerated the query is executed again and the objects are picked up from the source (each time mapping again your materialized entities to new DTOs).
To resolve, just turn your collection into a list before manipulating it:
var moviesDto = moviesQuery.ToList()
.Select(Mapper.Map<Movie, MovieDto>).ToList();