The original Movies controller hard-coded the DbContext as a class level variable, used a simplistic model, and leveraged the ViewBag extensively. The migrated site improves on this by using DI, a more advanced object graph, and View Models. Update the constructor for the Movies controller to accept the two repositories though DI. Then, add in a configuration for AutoMapper. See how to replace the code in the Index action method, and more.
- [Instructor] Now that we have completed the rest of the server side work, it's time to add in and upgrade the controller. So right-click on the controllers folder, add existing item, and we're going to pull in the movies controller from the MVC 5 project. Let's open that up, close solution explorer to give us more room; and we'll start out by just deleting these errant namespaces. We need to add in the ASP.NET core namespaces, so we let Visual Studio help us, control period, use ASP.NET core MVC, and we need heavy MovieDBContext from our data access library, which the difference here is a lower case b.
Now, we could go through and correct all these errors, but there are some changes we want to make. We certainly want to take advantage of the built-in dependency injection; but also a lot of code in the original sample was doing a lot of database work, which we've replaced with our reusable code in the repositories. So, first things first, let's create a constructor, public MoviesController; and in this constructor we're going to take two interface types, IMovieRepo, will also be called MovieRepo.
IMovieGenreRepo, and we'll call that movieGenreRepo. Let's fix our namespaces, control period; and then we're going to instantiate local fields with these values. So we'll say lower case movieRepo equals MovieRepo, and movieGenreRepo equals movieGenreRepo; and I even said lower case, but then typed in upper case.
There we go; now we just need to create these fields, and again we can let Visual Studio help us with that. And to be completely clear, let's just make these read only so we don't accidentally reassign them. So the repository classes will get automatically instantiated from the container because we set them up in the startup class. So if we go down here to startup just to confirm that we've done this, right here, anything within scope, which is the entire core MVC application, if a constructor sees an IMovieRepo being requested, it'll get populated with a movieRepo instance.
So let's start with the index, and there's a fair amount of code in here; and we are looking for a select list so that they can pick the genre, right? This was the filter part, and then we want to return the movies based on their search criteria or all of them if there isn't a search criteria. So let's make a new list of select list item and lots of namespace needing to be fixed here.
And we'll just call that movieGenres. It was this movieGenreRepo.GetGenres, which returns an IList of string. So then we want to take this list of strings and convert it to a list of select list items. So we will then say new SelectListItem where the text equals the value from the list and the value equals the value of the item from the list.
And then, finally, we want to have a new SelectListItem for the all selection; so there the text equals all, and the value equals an empty string. Call ToList on that to give us an actual list, and that takes care of this code here. Now this next line is assigning the genre list to a view bag property, but we're going to use a view model; in fact, a view model that we already created to carry that data forward.
To get the movies, we use our repository. So we could say var movies equals movieRepo.GetMovies, and we've already built the method that takes in the movie genre and search string, which replicates the code that we see here. Search string is not null. It looks for it in the title; and if the movie genre is not null, it looks for a matching genre.
This allows us to delete this code; and then instead of returning the view, what we will return here is the view model. So we declare the view model variable equals new movie index view model, and we'll use object initialization once we fix the using statements; and we have the movieGenre equals the movie genre from the action method, and the search string equals the search string from the action method.
And then movieGenres equals the list that we created up above; and there's one other property on the view model, and that is the movies. And we can't populate them yet. If we take a peek into the view model, you recall that it is an IEnumerable of MovieViewModel. So we have to change our movies into MovieViewModels, and for that we will use AutoMapper.
So the first thing we're going to want to do is create a mapping configuration; and if you haven't used AutoMapper, it is an awesome utility that allows you to very quickly and easily change one class to another class. So let's create a variable here, read only; and this is a MapperConfiguration. And let's fix the using statements; and we'll just call that MapperConfiguration, and we instantiate this in the constructor.
So our MapperConfiguration equals new MapperConfiguration, and this merely sets up or informs AutoMapper to create maps between two different types. And in this case, we want to create them between the movie type and the movie view model; and then we just have to bring in one more using, and we'll make that a little easier to read.
And now we can finish our view model, and what we want to add in here is that Movies equals MapperConfiguration.CreateMapper. We tell it to map to an Ilist of MovieViewModel, and then we pass in the object or the list that is the source of the data; and in this case, it's the movies collection that we had up above.
And then what we're going to return here instead of movies is the actual view model, and that finishes our index method.
Phil Japikse begins by showing how to install and update the .NET Core SDK. He reviews the functionality of the MVC 5 app, explains how to create necessary projects, and discusses migrating static content. Next, he demonstrates how to create a data access layer, complete the server-side migration, set up the HTTP pipeline, add custom items into the dependency injection container, leverage the new project configuration system, and migrate the controllers. Phil then introduces Tag Helpers—one the big new features in ASP.NET Core—and uses them to migrate and simplify the views. Phil also demonstrates how to create and use custom Tag Helpers. To wrap up, he covers working with view components, explaining what they are and why they're helpful. He walks through how to create the server-side view component code, and how to refactor your app and invoke the view component.
- Reviewing the MVC 5 application
- Creating the data access layer
- Adding and updating the models
- Updating the database
- Completing the server-side migration
- Configuring the HTTP pipeline
- Configuring and using dependency injection
- Migrating the views
- Creating view components