AspNetCore.Docs/aspnetcore/includes/mvc-intro/adding-model4.md

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:

[!code-csharp]

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:

[!code-html]

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:

[!code-csharp]

When you created the movies controller, scaffolding automatically included the following @model statement at the top of the Index.cshtml file:

[!code-html]

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:

[!code-html]

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: