5.6 KiB
The highlighted code above shows the movie database context being added to the Dependency Injection container (In the Startup.cs file). services.AddDbContext<MvcMovieContext>(options =>
specifies the database to use and the connection string. =>
is a lambda operator.
Open the Controllers/MoviesController.cs file and examine the constructor:
The constructor uses Dependency Injection to inject the database context (MvcMovieContext
) into the controller. The database context is used in each of the CRUD methods in the controller.
Strongly typed models and the @model keyword
Earlier in this tutorial, you saw how a controller can pass data or objects to a view using the ViewData
dictionary. The ViewData
dictionary is a dynamic object that provides a convenient late-bound way to pass information to a view.
MVC also provides the ability to pass strongly typed model objects to a view. This strongly typed approach enables better compile-time checking of your code. The scaffolding mechanism used this approach (that is, passing a strongly typed model) with the MoviesController
class and views when it created the methods and views.
Examine the generated Details
method in the Controllers/MoviesController.cs file:
::: moniker range=">= aspnetcore-2.1" [!code-csharp] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp] ::: moniker-end
The id
parameter is generally passed as route data. For example http://localhost:5000/movies/details/1
sets:
- The controller to the
movies
controller (the first URL segment). - The action to
details
(the second URL segment). - The id to 1 (the last URL segment).
You can also pass in the id
with a query string as follows:
http://localhost:1234/movies/details?id=1
The id
parameter is defined as a nullable type (int?
) in case an ID value isn't provided.
::: moniker range=">= aspnetcore-2.1"
A lambda expression is passed in to FirstOrDefaultAsync
to select movie entities that match the route data or query string value.
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.ID == id);
::: moniker-end
::: moniker range="<= aspnetcore-2.0"
A lambda expression is passed in to SingleOrDefaultAsync
to select movie entities that match the route data or query string value.
var movie = await _context.Movie
.SingleOrDefaultAsync(m => m.ID == id);
::: moniker-end
If a movie is found, an instance of the Movie
model is passed to the Details
view:
return View(movie);
Examine the contents of the Views/Movies/Details.cshtml file:
By including a @model
statement at the top of the view file, you can specify the type of object that the view expects. When you created the movie controller, Visual Studio automatically included the following @model
statement at the top of the Details.cshtml file:
@model MvcMovie.Models.Movie
This @model
directive allows you to access the movie that the controller passed to the view by using a Model
object that's strongly typed. For example, in the Details.cshtml view, the code passes each movie field to the DisplayNameFor
and DisplayFor
HTML Helpers with the strongly typed Model
object. The Create
and Edit
methods and views also pass a Movie
model object.
Examine the Index.cshtml view and the Index
method in the Movies controller. Notice how the code creates a List
object when it calls the View
method. The code passes this Movies
list from the Index
action method to the view:
When you created the movies controller, scaffolding automatically included the following @model
statement at the top of the Index.cshtml file:
The @model
directive allows you to access the list of movies that the controller passed to the view by using a Model
object that's strongly typed. For example, in the Index.cshtml view, the code loops through the movies with a foreach
statement over the strongly typed Model
object:
Because the Model
object is strongly typed (as an IEnumerable<Movie>
object), each item in the loop is typed as Movie
. Among other benefits, this means that you get compile-time checking of the code: