Building Your First ASP.NET Core Web Application


  1. Course Overview Hello and welcome to this Pluralsight course named Building Your First ASP.NET Core Web Application. My name is Gill Cleeren and I'm pleased that you are interested in learning how you can build a fully working ASP.NET Core application. I'm going to do my utter best to show you in a time span of about four hours how you can learn how ASP.NET Core MVC works and what are the great new features in this shiny new release of the platform. This will be a very practical course, focused on the doing. That means that you can follow along and build the site together with me. By the end of this course, you'll have a fully working web application that you can use as your reference for your own ASP.NET Core MVC apps. In this first module, I'm going to be discussing the following topics. First to set the expectations right from your site, I'll spend a couple of minutes to explain you what you'll be learning in this course. We will also explore the final application. This will, I hope, motivate you to build this web app together with me. Next, I'm going to briefly talk to you about the ASP.NET Core framework and what are some if its main concepts. In this part I'll be giving you some of the basic concepts that are important for the rest of this course. And as mentioned, this course is a practical course so you can follow along with everything I'm doing. That of course requires that your machine is fully set up to get coding. In this last part, I'll be giving you a quick overview of what you should be installing before continuing the next chapter. First, a brief overview of this course is in place I think. The main goal of this course is learning how ASP.NET Core MVC can be used to build a fully working website. I'll focus on giving you the full picture of how to build a real world application with ASP.NET MVC Core. After finishing this course, you'll be able to use ASP.NET Core and build yourself web applications with this new framework. The approach I'm using is pretty simple. I'll be starting together with you in the next module with File, New Project and we'll build a site together. That means that you'll be seeing quite a lot of code. But I think that is the best way to learn. And in a couple of hours, you'll be a proud ASP.NET Core MVC developer who has created his or her first ASP.NET Core MVC site. Sounds great doesn't it? Now ASP.NET Core is probably the biggest change that together with .NET Core was ever introduced to the .NET platform since its inception many years ago. While we work our way to the final application, you'll of course be learning quite a lot of things including of course, ASP.NET Core and .NET Core. You'll also learn about MVC so the pattern itself used for the app we are building. You'll see what was added in terms of new features in this release. We'll also be looking at Entity Framework Core. We will cover how we can build security into our site and finally we'll also learn how we can deploy the site to Azure. I reckon that's a useful couple of hours of learning. Since we are focusing on the practical side of things, I won't be trying to make this course into a course where I'll be discussing every new feature in the platform. Instead I'll focus on what you need to get to a working site. With this you'll have enough knowledge to explore the rest of the platform where needed. Now you may be thinking what is he expecting me to know since I'll be needing to write a lot of code in this course? Well, the prerequisites for this course are pretty basic. I expect that you have some knowledge about HTML and CSS. You certainly do not have to be an expert, no worries there, just the basics will do. Since we are using ASP.NET Core MVC, we will be writing our code in C#. Again no expert knowledge is required here. And I do hope that you have some affinity with web development in general and since you're watching this course, I think that'll be the case anyhow. So you see, no ASP.NET MVC knowledge required. Indeed, that's correct. This course will be useful for both people who know ASP.NET MVC already as well as people who have never written a single line of ASP.NET MVC code. So no MVC knowledge, no worries. However, if you already have previous MVC knowledge, you'll be able to learn a lot of new stuff in this course as well. You'll see how the new features work and how they can be put into practice in the end to end application that we are building. Now you may be a bit curious about that website that we'll be building together. At least I hope I have made you curious a little bit. We are going to create together the web shop for Bethany. Bethany is a young entrepreneur who is baking the world's best pies. And although her store is doing great, she wants to let people who can't make it to her store also enjoy these great pies. I must say, I'm pretty happy that she came up with that idea. Now Bethany came to our office pretty recently and she asked us to create her web shop. Now Bethany is a bit of a technology lover and she said that since she's a young starter she wants this website to be capable of running a couple of years without needing to upgrade pretty soon to a new version already. So we should be using the newest technology stack available. "Well Bethany," we said, "we are going to create your website "with ASP.NET Core MVC." The finished version of this web shop offers a number of pages where we can browse through the pies she's selling. Of course it's a web shop and thus will also need a shopping cart. Security, so logging into the site will be implemented as well. And finally since her pies are so great, we expect a lot of traffic on her site so we are going to deploy her site onto Azure so we can easily scale when things are getting busy.

  2. Demo: Taking a Look at the Finished Application Now let's take a look at the finished site in the first demo of this course. Please note that I'm not taking any responsibility if after watching this course, you get hungry for a nice piece of pie. What you see here is the final application that we will be building throughout this course so Bethany's Pie Shop. As you can see this website has a landing page with a banner and some pies of the week. There's a menu at the top with a Home button, a Pies sub-menu and a Contact Us page. When I select here Cheesecakes, I will see a list of all cheesecakes that Bethany has to offer. I can also take a look at a list of all pies, as you can see here. When I then click on one of the pies, I can see the detail of that delicious pie. From here I can also add the pie to my cart and I will then get an overview of my shopping cart. Also note here at the top, I can see that I now have one pie in my shopping cart. Let's add another one. Let's add this blueberry cheesecake. And now I have two pies in my shopping cart. I can now check out. The site will ask me to log in. I've already created an account. When I then log in, I go to this check out page where I can now enter all my details. Let me do that very quickly. And I will now click on Complete Order. I will see a page that thanks me for my order. Finally I also have the Contact Us page from where I can contact Bethany using this Contact Us button. So I hope that you like Bethany's Pie Shop and we're going to build this together in this course. Now that you've seen the working website, please make sure that you download the source code if you want to follow along with me. You can find the start and end solutions for all modules in this course in the Exercise files.

  3. An Introduction to ASP.NET Core Now that you have a good idea what you will be creating in this course, I would like to give you a small introduction of the ASP.NET Core platform. Announced late 2014 and released in June 2016, ASP.NET Core introduces probably the biggest shift the platform has experienced so far. Let's take a look at how we got to this important point in the history of ASP.NET. Many years ago, to be precise, in 1996, Microsoft introduced a framework called Active Server Pages and it was commonly known as ASP. Now it's sometimes also referred to as Classic ASP. Now with Classic ASP, Microsoft made it possible to have server side scripting to dynamically create web pages. The biggest revolution came with the introduction of the .NET framework. Microsoft introduced ASP.NET WebForms to counter some of the common problems that developers at the time were facing. WebForms was definitely an abstraction on top of web development, making the creation of web pages very similar to creating Windows applications which was common knowledge for developers at that time. While it was an awesome framework to quickly create pages with, it definitely had its down sides. If you've ever done or seen ASP.NET WebForms pages and the source code that they created, undoubtedly you have seen the ViewState, a hidden field which was generated automatically by WebForms. WebForms tried to make the stateless web stateful and to get to that point, it did a lot of plumbing to let pages retain their states or their values automatically. The ViewState as the name implies, contained those values and that resulted in a lot of data being generated and transferred over the wire with each request often without there being any real requirement for this. Another thing that WebForms was doing which is frowned upon now, it was hiding all the details of HTML. As developers we had almost no control over the HTML that was being generated by the controls that we dragged onto our pages. On top of that, the generated HTML was all but clean which in today's web would not be acceptable. WebForms was the first version to introduce code behind. Now code behind is a good idea but it can lead to code which is hard to test. Typically we would write code and on one line read from the database and on the next is updating the UI. That sort of code is difficult, if not impossible to test. Another common issue was the page life cycle. When requesting a page, a number of events were fired. Getting to know this page life cycle was actually quite difficult and it was easy to get it wrong. Although it had quite a few down sides WebForms certainly was a great technology to get a site up and running quickly. A couple of years later, more specifically in 2009, Microsoft officially released the first version of ASP.NET MVC. Now with MVC the company tried to overcome most of the problems it was having with WebForms. MVC asked developers to create clean code through complete control over the HTML and CSS. Also, since the emphasis is on the separation of concerns, MVC code is typically much easier to write unit tests for. MVC was also the first edition they released as open source. This marked a big change for Microsoft and we are still seeing the results of this today with .NET Core where everything is open source by default. MVC has evolved quite a lot over the last years and the platform has over the years received many updates and extensions. Now although a lot of developers love the MVC framework today, it also has its flaws. When it was created it was built on top of components Microsoft had already created for WebForms. That caused the framework to still be closely tied to quite a number of already aging technologies and frameworks. ASP.NET MVC being built on the foundation of WebForms is still using System.Web and runs on IIS exclusively. It's also tightly coupled with the .NET framework. Although Microsoft has updated MVC separately from .NET it was still bound to large releases. On the other hand, the web is evolving very quickly and it therefore became difficult for Microsoft to let ASP.NET MVC keep up with everything that was changing. Finally, MVC was born before we all were moving to the cloud. Although tons of MVC applications today are running on the cloud, it's not built with the cloud in mind. Now in June 2016, Microsoft released a new version of .NET, being .NET Core and together with that ASP.NET core. ASP.NET Core MVC is as you already know the focus of this very course you're watching right now. Now ASP.NET Core is built on top of the new .NET core framework. .NET Core is the very first cross platform version of .NET and is therefore not tied any longer to just being used on a Windows environment. Using .NET Core, we can now create .NET apps and web applications that run on multiple operating systems including Linux and MAC OS. In today's world that is definitely a good thing. ASP.NET Core is compared to the old MVC also not tied any longer to the .NET framework assemblies such as System.Web. Let me discuss briefly some of the important benefits that we are getting from moving to ASP.NET Core for our web development. If you've never done any MVC development, this may be a bit hard to understand, however, all these benefits will become clear when we are moving through this course. There is now a unification between ASP.NET MVC and the Web API. Where we had different controllers in the past, we don't have that anymore with ASP.NET Core. Dependency injection. So the ability to plug dependencies in our code from the outside is now a core feature of the platform. Although previous versions of MVC had support for dependency injection already, ASP.NET Core has been built with dependency injection in mind. We'll be using throughout the entire creation of our application the dependency injection container very often. ASP.NET Core has a modular request pipeline. We'll see how we can make use of this when we work with the middleware later in this course. NuGet has also been integrated deeply into ASP.NET. You'll soon learn that everything in ASP.NET Core is a package and packages are managed using NuGet. ASP.NET Core has been created from the ground up with cloud in mind. In this course we are going to deploy the final application to Azure. Remember that I said that ASP.NET MVC was tied to just running on IIS? Well that's another issue which we'll solve with ASP.NET Core. While we can of course still run our ASP.NET Core apps on IIS, we can now also host them in our own process. ASP.NET Core is also fully open source and cross platform. I think you'll agree with me in saying that ASP.NET Core is a big change for the ASP.NET platform. The very first version was released in June 2016. In this fee one release, we are getting a fully working framework that allows us to write several types of applications. We can create using .NET Core console applications, of course ASP.NET Core MVC applications, Web API's and we can create the new Standard Libraries. While ASP.NET Core MVC is fully working, not everything of the MVC framework has been ported already to the Core implementation. At the time of the creation of this course, which is late 2016, the .NET Core and the ASP.NET Core MVC framework are in a V1.1 state and many things which aren't there at this point yet, will be included in future updates.

  4. Getting Your Machine Ready I hope that you now understand that ASP.NET Core is a big release and that you have decided that you want to learn all the goodness that comes with this release. So time to get started then. Let me show you what you'll need to install to follow along with this course. In this course I'll be using Visual Studio 2015 with Update 3 installed. At the time of creation of this course that's the latest and greatest. .NET Core and ASP.NET Core weren't available at the time of the release of Visual Studio 2015 Update 3 so they did not get installed automatically. You'll have to download the .NET Core Tooling as well. I'll show you in the next demo where to download all this from and of course, the most obvious one, you'll need a browser as well. But I think you could have guessed that already, is it not? Now since .NET Core and ASP.NET Core are cross platform, it's now for the first time possible to create an ASP.NET web application using other operating systems, so Mac and Linux. For these platforms you can download Visual Studio Code. They're free, lightweight and they're from Microsoft. It doesn't come with C# support out of the box so you also will need to install a plugin for this. Alternatively, .NET Core lends itself to being used from just any OmniSharp-ready editor including Atom, Sublime, or even Vim and it is now because of .NET Core possible to create ASP.NET Core apps using this legendary editor.

  5. Demo: Getting Your Machine Ready Let me show you in this last demo of this course the tools that you'll need to download to follow along with this course. For this course you will of course need Visual Studio to be installed. You can go to Visualstudio.com/downloads and download the Visual Studio Community edition. Pay attention that you download the 2015 edition as that is the one that I'll be using in this course. Of course all other editions such as Professional or Enterprise will also do for this course. When you have Visual Studio installed, go to Microsoft.com/net and then you'll arrive on the .NET homepage. Over here go to downloads, click on .NET Core and then you'll be able to download everything you need for .NET Core. As you can see, currently it says here that the LTS, so the Long Term Support version is the 1.0.1 release. That is the one I'm using here in this course. You will need to install either the X64 or the X86 package and you'll also need to install the tools for Visual Studio. Pay attention that you download the Visual Studio 2015 tools. Microsoft has already released an update which is .NET Core 1.1, however, for what we are using in this course, we can still use the 1.0 release. If you have already installed the 1.1 don't fear, everything will still work. This course was created late 2016 and Microsoft has announced that changes are coming to their tooling. When the tooling used in this course will be updated, this course will also be updated.

  6. Summary Now with that we've reached the end of this module. I'm pretty sure that I have convinced you that ASP.NET Core is the next big thing for ASP.NET. It's where all the investments from now on will go to, that's for sure. The world is moving towards both open source as well as cross platform and those are the gaps that this version is filling. ASP.NET Core is ready for prime time. You'll see more and more things being added to the platform as well as even better support from the tooling. In the next module, we are going to get started building Bethany's Pie Shop. I hope to see you there as well. Thanks for watching.

  7. Setting up the Solution Module Overview Hello, and welcome again to the Building Your First ASP.NET Core Web Application course here at Pluralsight. My name is Gill Cleeren and I'll be guiding you through this module. If you've watched the previous module on this course, you will already know that ASP.NET Core is a radical change compared to earlier versions of the product. In this module, I'll be showing you already some of the big changes that come with this new version, while we will be setting up the solution and the project for Bethany's Pie Shop, so by the end of the module, you'll understand how ASP.NET Core MVC projects are structured, and configured, and you'll also understand the goal of the different files in an ASP.NET Core MVC project. It's a good tradition to start a module with an overview of what exactly you'll be learning and doing in this module; since this module is named Setting up the Solution, I'm going to start by doing exactly that. We'll be starting from file, new project, and next we'll take a look at what is being generated; I will guide you through the project structure, explaining you the important files and how they are used in ASP.NET Core. This new version offers a very flexible way to configure the application; previously, when talking about configuration, we immediately thought of a config file. Those days are gone, you'll learn how we can do the basic configuration of our site so that we can start adding pages in the next module. Let's dive in, shall we?

  8. File -- New Project All good things start with something very simple, so let's get started with file new project. Before we start doing this in the demo, I want to give you an overview of the available options we are getting from Visual Studio. With ASP.NET Core installed in Visual Studio, under the webnotes, you'll have the ability to tick off the development of your ASP.NET Core MVC project; make sure that you select the note that says .NET Core between brackets, as you can see in the screenshot here. Visual Studio will present us with a number of choices. The empty ASP.NET Core template generates, well an empty site; I believe that is where it got its name. Secondly, there's also a template for an already-configured web API project. We are in this course only going to cover working with this new web API briefly. Other courses here at Pluralsight are covering this in much more detail. Finally, there's the web application project template, which is an already configured ASP.NET Core MVC web application. If we just take the empty application template, which we'll be doing in the upcoming demo, the result is pretty basic as you can see here. Just about nothing is configured by default. And the only thing this site can do at this point is returning a string; while that is pretty basic, I am going to use this as our starting point, so I can set up everything manually and while doing so, explain you everything that is going on under the covers. If you would execute the web application template, then you'll be seeing what you see here on this screenshot. As you can see, the site already has some nice looking UI, based on bootstrap, by the way; it also comes with a number of pages already in there, and the site has already been configured for basic ASP.NET Core MVC support. While it's nice to give us a head start, as mentioned I won't be using this template in this course.

  9. Demo: Creating the New Solution So without further ado, let's jump into Visual Studio and create that new project. I encourage you to follow along from here on, if you want to build the application together with me. I am here in Visual Studio, and I'm going to create the new solution, so I'm going to go to file, new project, and then, select .NET Core as you can see over here. Then I'll select the ASP.NET Core web application and I'll give it the name Bethany's Pie Shop. Note that I have unselected the add application inside the project. I click okay, and I'm going to take the empty web application; I've at this point unselected hosting cloud, I hit okay, and now Visual Studio will execute the template and create the application for me. I now click here on IS express, I will start the empty website. So we only have a hello world showing up at this point. We still have a lot of work. Let's start exploring the solution.

  10. Looking at the Project Structure The creation of the project was pretty simple; now that you have the created, although still empty, project ready, before we start adding any code to it, it's a good idea to explore what is in there. If you have any previous ASP.NET MVC knowledge, you'll see that quite a few things have changed here. Let's take a look. On the screenshot of the solution explorer, you can see here on the slide, you'll see the files and the folders which are currently in our solution. One thing that's important to notice here is that all the source code for the site is now in an SRC folder by default. The idea here is that all code inside of our solution is grouped in this very folder, and that we can add other folders, for example for tests or for documentation files. It's not a requirement that this folder has this name, but since this is the folder that gets created by the template, I can imagine you'll see most projects following this structure from now on. Inside the src folder, we have the web project. Inside, you can find references as well as the files that will make up our application. Another important change that is coming with ASP.NET Core MVC is the wwwwroot folder, that's been created automatically. In this folder we will be placing all static files, so images, css, Javascript files and static HTML files, they will all go in this folder. This folder is the root of our site, so in our case, Bethany'sPieShop.com will be pointing to this wwwwroot folder. None of the code files that we will be creating will go in this folder, so you shouldn't be placing any C# or Razor files in this folder, this folder is created mainly with the idea of having a nice separation between the code files and the static files. You may have already noticed the presence of several JSON files in there. In this new version of ASP.NET, JSON is going to play a very important role. It's now being used as the format for configuration files. In the solution root, you'll find the global.JSON and in the project itself, you'll find the project.JSON file; the global.JSON file is used to let Visual Studio know where to find the project in the solution. We won't be working with this file directly in this course, however the second one will play an important role in this course. The project.JSON file will be used to specify which NuGet packages will be installed in our application. You'll soon learn that just about everything in Asp.NET Core MVC is a package, hence the project.JSON file will play a very important role going forward. Next to describing the NuGet dependencies, the project.JSON file will also be used for other configuration of our application. Let's take a moment to look at the project.JSON file which is generated by default. We'll take a look at this file in the demo as well, but I want to give you some information here already. As you can see, the file comes with a number of sections, each allowing us to manage different types of configuration. For example in the dependencies part, we'll be placing our NuGet dependencies, and in the tools section, we'll be adding, later in this course, which packages we'll need as our development tools. At this point, as you can see in the previous demo, the site is still pretty basic. In fact at this point, it doesn't even support MVC. Now let that sink in, that is because all the functionalities that we want in our application are to be added as a package; indeed, everything in .NET Core is a package, that's what makes it so lightweight and configurable, you only pay for what you use, that's the motto now. So let's take a look at the dependencies section here. As you can see, the list is pretty short. These are the packages that were added by the template. At the bare minimum, you should be adding the packages that you see highlighted here. These are adding support for MVC in our site, amongst others. MVC itself is a package, the site doesn't come with MVC support enabled by default. Static files is another one we have added here. ASP.NET Core does not have support built in to serve static files; we'll have to add another package to add this support. Also the Razor tools package needs to be added here. To get things working at a basic level at this point, you will also need to add some packages to the tools section of the project.JSON file. These packages will enable functionality during the development of the application. As you can see, I've added the Razor tools package here as well; this will enable inter-license support at design time, for tag helpers in Razor views; don't worry at this point what tag helpers are, we'll be using them quite a lot later in this course. And by the way if the concept of Razor isn't clear to you at all, just wait until the next module to learn about it. Just for now, remember that to have IntelliSense support, this package needs to be included here.

  11. Demo: Adding the Correct NuGet Packages In this demo, we are going to start by exploring in a bit more detail the generated project. Next, we'll start making changes to the project.JSON file, so it will contain the required NuGet packages already. Let us now explore the generated solution, the empty solution at this point still. So the solution is called Bethany's Pie Shop, and we already can find a JSON file here, which is called global.JSON. In that file we can see that projects are to be found in the source, the src, directory. And we can see that all the code is actually going to be inside of this src directory. The actual web project is this Bethany's Pie Shop here and in the actual project, there's a couple of interesting things to note. We have a wwwroot folder, all the static files such as CSS, Javascript, but also libraries that we are going to download, such as J query, are going to live inside this directory. This is considered the root of the application project. We're not going to put any MVC code in there though, that is all going to go in different folders. A very important file here is this project.JSON, let's explore this file for a minute here, all dependencies that we'll have in our application are going to be managed from this project.JSON file. There is this dependencies entry here, which will list all the dependencies that we'll have in our application; at this point, the application has still very limited functionality. When we executed the application in a previous demo, all we could see was hello world. It is at this point not even an MVC application yet. Let's change that; I'm going to bring in a couple of extra dependencies. This will add extra functionality, extra packages, to my application. For example I've added support for Razor; we'll talk about Razor quite a lot later on. I've also added support for serving static files, and I've also added support for the MVC package. In the tools section, I also need to bring in another package, it's the same package that we've added here in dependencies, support for Razor, when we add packages in the tool section, we'll be able to use them at design time, let's save the file and take a look at the solution explorer. What will happen is that Visual Studio is now restoring packages, and we take a look at the references, we see that our packages have indeed been downloaded. At this point, we've now simply added some packages through the project.JSON file in our application.

  12. Other .NET Core Files In the root of the application, we can also see a file called Program.CS; what is this file all about then? Well in the Program.CS, we can find a main method, so that's an entry point. The main method here can be executed to configure the hosting environment. The letter includes making sure that the application services and the server are configured correctly; now, for the creation of Bethany's Pie Shop, you will not have to change this, in fact in most cases you won't be needing to change this file at all. We will at the end of the course deploy our application to Azure, and for that, this default will do fine.

  13. Configuring the Application We've now seen most of the files in the generated project. However, there's one very important thing I haven't covered yet, and that is the configuration of the ASP.NET Core MVC application. If you're familiar with ASP.NET MVC, this again will be something entirely new for you. Looking once more at the default generated files, there's one file that we haven't spent time looking at, and that is the Startup.CS file. This file, or better, the class within this file, will be used for the configuration of the application. The code that you see here on this slide is generated automatically by the template. It contains the Startup class, and the Startup class in turn contains two methods, ConfigureServices and Configure. We'll have to write code in here already at this point, but also quite often during the rest of the course, you'll see me returning here to add more configuration code. At this point, the code you see here was actually responsible for showing the hello world message that we saw in the beginning of this module. Of course, that's not really helpful, so we'll need to add some more configuration code in here at this point. Now how is this Startup class used and what is its function, now when the application is started, a new instance of this Startup class will be generated, and first the ConfigureServices method will be invoked. This allows our application to create its services. Now services is a very broad term, and it is in fact exactly that. Services are objects that have a certain functionality for other parts in the application; we'll be able to instantiate baked-in services as well as our own, but more on that later. After that, the Configure method will be invoked on a start-up instance. Using this method, the request pipeline will be set up. Request pipeline consists out of a number of components, changed behind one another. These are so-called middle-ware components and these components will intercept or handle incoming HTP requests and produce an HTP response. These components will intercept or handle incoming HTP requests, and produce an HTP response. To configure our application, we'll need to add both services as well as some basic middle-ware components. At the bare minimum, in order to get MVC support in our site, for the services we'll use the AddMVC extension method; this is a method that, behind the scenes, configures a number of other services for MVC to work. Next, in the Configure method and set, I can register so-called middle-ware components. Here, we'll be using the IApplication builder instance to create the middle-ware pipeline. What I'm doing here is I'm registering four middle-ware components at this point. First, I'm using the UseDeveloperExceptionPage. This will enable the use of the Developer Exception Page, in my application, so that we will get useful error information during development. The UseStatusCodePages method will add support for text only headers for common status codes. UseStaticFiles is another middle-ware component that I'm registering here, and that will enable the ability for my site to serve static files. Finally, the UseMVCWithDefaultRoute sets up the MVC middle-ware using the default routing schema, don't worry about routing just yet, we'll come to routing in much more detail later in this course.

  14. Demo: Configuring the Application Now that we know more about the configuration of the Startup class, let's go back to the demo and make the required changes in our code. At this point we only have added packages, we haven't used them in the configuration of our application just yet. To do that we'll have to use the very important Startup class; as mentioned in the slides, the Startup class will be invoked automatically from the runtime and two methods in here will also be automatically invoked. Those are the ConfigureServices and the Configure method. The ConfigureServices has the IService Collection parameter, called services, and that's basically our dependency injection system. We can add extra functionality to our application by registering services with this collection. The most basic service I'll need is of course MVC, so what I'll do is I'll add MVC support, by adding Services.MVC; as mentioned, the Configure method will also be invoked automatically from the .NET Core runtime. In this method, the pipeline, the request pipeline let's say, will be created, and we have the ability to add extra components to that request pipeline, and these are the actual middle-ware components. I'm going to remove the code that is in here by default; the code that you see here by the way was responsible for showing the hello world that we saw earlier, but we want some extra functionality for Bethany's Pie Shop, so I'm going to remove this and I'm going to add some very basic middle-ware components already. Let's take a look at what I've added here; the UseDeveloperExceptionPage method is adding support for showing exceptions in the browser when something goes wrong. By default, it's not there; .NET Core is just offering us, by default, the bare minimum. The UseStatusCodePages method allows us to handle response status codes between 400 and 600; UseStaticFiles allows us to serve static files, and finally, UseMVCWithDefaultRoute, well, as the name implies, it's adding support for MVC and it's doing that with support for a very simple route. We'll use that very basic route in the beginning of this course, we'll later on look at how we can use custom routes. If you don't know what routes are just yet, don't worry, we'll come to that later on. Running the application at this point will not do anything, because we haven't added any controllers or views just yet; we'll do that in the next module.

  15. Summary Our project is now correctly configured, and we are ready to start adding pages to our site. Now that this module is finished, you have seen that ASP.NET Core is much more modular, we have fine grained control over what packages get added; each package enables extra functionality in our web application. Now to support this, the structure of an ASP.NET Core application is pretty different compared to different versions of ASP.NET. We've seen this new structure in quite a lot of detail in this module. Let's head over to the next module, where we will finally be creating our first page together, end to end. I hope to see you there as well, thanks for watching.

  16. Creating the Overview Page Module Overview Hello, and welcome again to this Pluralsight course, where we are building together our first ASP.NET Core MVC application. I'm still Gill Cleeren, some things never seem to change, isn't it? We have, in the previous module, prepared the solution for our application, and we're now ready to start adding pages to the site. In this very module, we are going to do exactly that. We are going to create the overview page. So at the end of the module, you have already a good understanding of how you can create new pages in an ASP.NET Core MVC site. Of course, before we start with the actual work, let's take a look at what, exactly, I will be explaining you in this module. First, a short word about the MVC pattern is in place. If you don't know what this pattern stands for, I'll give you the information you need right here. Then, we are going to create the page from, well, let's say, the bottom of the stack, all the way up to the actual view. So we'll start with the lowest items in the stack. We are going to start with the creation of the model, then the repository, and then the controller. After that, we are going to create the view. I'm not only to create the view, but you'll also understand how views are matched with the controller. And finally, I'll also add some styles to our site. Our site will be basing its layout on Bootstrap, and we'll see how we can add this in an ASP.NET Core application. This is going to be a very rewarding module, since you'll be able to run your site by the end of this module, and actually see the result of your hard work.

  17. Looking at the Finished Overview Page Before we start with the creation of the page, let's quickly take another look at the page, so you know exactly what we are going to be working towards. Just as a small refresher, this is the overview page. In fact, it's a simplified version of the overview page that we will be building, we will be adding more features in later modules. But just to give you an idea, this is what we'll have by the end of this module.

  18. The MVC Pattern Since this course is all about the MVC pattern used in ASP.NET Core MVC, it's important that you understand the MVC pattern. Let's start with that. It's pretty logical that ASP.NET Core MVC is all about that oh so common pattern, the Model-View-Controller pattern. This is an architectural pattern, which is focusing on the separation of concerns. Basically, this means that each of the building blocks should have its own functionality, and focus on that. This results in a more loosely coupled system, and the net result is that we'll get software that is much more testable and maintainable. So in MVC, we'll typically have three building blocks. The models contain the data the user works with. These are the domain model classes, as well as operations to work with this data, often referred to as the model logic. Typically, the classes in here represent everything in the model that we are going to work with. So in the case of Bethany's Pie Shop, we'll have a pie class, we'll have an order class, and so on. Controllers are the glue between the model and the view. Controllers will provide the logic that works on the data model, and provide data for the view to display. The views, finally, will contain logic to display data to the user, so that it can again be processed by another controller action. And we'll look at the flow that we'll get in ASP.NET Core MVC, we'll see that a request will be arriving with one of the controller classes that we'll have. Controllers have so-called action methods, which are public methods that get associated with a URL. So when the user browses to a certain URL, the specific method on the controller will be invoked. This, in turn, will trigger code on the model, and then a view will be selected to display the data from the model to the user. Views in ASP.NET Core MVC are using something called Razor, which is the view engine. If you know Razor from previous versions of MVC, you'll see that in terms of Razor, not much has really changed in that area with the release of ASP.NET Core. Now that we know a bit more about the MVC pattern, we are going to take up the work for this module by looking at the layers under the actual view. So the model, the repository, and the controller. Typically, you'll see that a lot of ASP.NET applications are using the same folder structure. Although you can definitely do this in your own preferred way, I'll be using the following folders to place all my classes in. In the Models folder, we'll place all the classes that have to do with the data, so the model and the repository classes. In the Controllers folder, we'll of course be placing our controllers, and we'll have a Views folder, as well, where I'll be placing all the view files in. This will be the structure I'm using throughout this course. Let's take a look at the models first. The model in our ASP.NET Core MVC app will be a representation of a domain model class, and will also contain the logic for working with that data. The API that we'll have on this model layer is pretty simple in most cases. It just offers a clean and simple way of working with that data. It should also be abstracting away, to the layers above it, how the actual data retrieval is done. The above layers should be agnostic about this. Here we see a typical domain class that we'll have for our application. The Pie class, as you can see, is a POCO, a Plain Old CLR Object. The class isn't inheriting from any base class. It just has some basic properties, as you can see. You may be wondering, why do we have that virtual category property down there, at the bottom? That has to do with Entity Framework, and we'll take a look at that later in this course. Next to the actual domain classes, our model will also contain classes that contain the logic to create, manage and update our domain data. These are the so-called repository classes. These classes handle the internals for working with the data, but abstract away the details of how data gets persisted to the database. On this slide, you can see the code for an interface that I'll be using to expose the Pie model classes. By the way, we'll see this in action in the demo in just a second, no worries. The methods and properties you can see here are the typical things to expect on a repository. We are exposing an IEnumerable in Pies, and another one, PiesOfTheWeek. Also, a method to retrieve a Pie by ID is available here. The implementation of this class will contain logic to get the data from somewhere, typically, a database. The user of this repository is, however, agnostic about that. It doesn't need to know the details about how it should be loading data in this Pies collection. And in this module, we are going to be using mock data. We'll only link our application with a real database in the next module. Working with mock data, for now, can be done by creating a repository called MockPieRepository, that of course implements the interface we've just looked at. This can, for now, return hard coded data, and we'll do this in the demo in just a minute. Now, our repository class. So the mock repository will be consumed by another class. Traditionally, what we would be doing is creating an instance in the code of the consumer. This would, however, create a hard link between the consumer and the repository class itself. Remember that MVC was all about loose coupling, and here, we are considering of creating tight coupling. That's not good, there has to be a better way. Now the solution lies in dependency injection. Dependency injection allows us to plug dependencies, in this case, the MockPieRepository, in our consumer class dynamically. Dependency injection, or DI, is very common today, and used in many technologies. And in fact, it is so common today that ASP.NET Core MVC comes with support for dependency injection out of the box. What we are going to be doing is registering our dependency, in this case, the MockPieRepository, with the DI container. The latter basically keeps track of all the dependencies that our application has. The consumer can then simply ask the container for an instance when needed. This way, we are creating a loosely coupled system. Now in ASP.NET Core MVC, we can register dependencies in the Startup class, in the services collection. Let me show you how this is done. The code that you see here is part of the ConfigureServices method, which lives in the Startup class. This method gets, as parameter, an iServiceCollection instance. This represents all registered services of our ASP.NET Core application. Take a look at the highlighted line here. I'm asking to add to the services collection the MockPieRepository as an implementation of the iPieRepository interface. Basically, this means that from now on, when somewhere in my code, I ask for an IPieRepository, I will get back a MockPieRepository. This is important, since my consumer of the repository doesn't have to create an instance itself. Indeed, it will receive it from outside. This dependency is being plugged into the consumer, creating a loose coupling. Now one more thing, I'm using the AddTransient method here. This will result in a new instance of the MockPieRepository being returned every time I ask for an IPieRepository. Now next to the AddTransient method, we can also use other methods to register our dependencies with the service provider of ASP.NET Core. For example, the AddSingleton method results in a singleton being created. Every time we now ask for an instance, we'll get back the same instance. And there's another option called AddScoped. Scoped lifetime services are created once per request within the scope. So basically, MVC creates one instance for each HTTP request, and uses that same instance in other calls within that same rep request. We'll see these methods being used when we build up our application. Next to the model, we have the controller. You can consider the controller as a traffic agent for an MVC application, since it handles all the flows after a request was received. A controller will typically be invoked after the user has done some interaction. This results in a URL being requested, and a method on the controller, referred to as an action method, being invoked. This triggers the execution of code, which will work with the model classes we've just seen. The controller is the consumer of these model classes. It just uses these methods without knowing the details about how the data is being persisted. A controller is, in fact again, just a class. In this case, however, there has to be a base class that we are inheriting from. This base class, of course, comes with ASP.NET Core MVC, and it is simply called Controller, as you can see here on this slide. On the controller, we'll have methods, the action methods, or actions. In the most basic form, the controller will return the view that is supposed to be shown to the user without any logic being executed. We'll see more about the view in the next topic of this module. Here, you can see an already slightly more complex controller. It's using, or I should perhaps say, consuming an iPieRepository instance. Note the very important constructor parameter here. An instance is being passed in here through constructor injection. So what happens is that, automatically, the built-in dependency injection system of ASP.NET Core will look in the registered services for an IPieRepository registration. It will find it, and return, or plug in, let's say, a MockPieRepository instance into our controller.

  19. Demo: Adding Models, the Repository, and the First Controller We've now covered a lot of ground already. Time to start creating all this. In this demo, I will create some of the domain classes already, we'll add a repository class, and then we'll register this with the service provider. Finally, we'll also take a look at the first controller, the PieController. All right, let's get started by writing some code. As you may have already guessed, there's quite a lot of code that needs to be written for this application. And I think it's quite boring that you see me type, so I'll be using quite a lot of snippets throughout this course. Now if you want to follow along, I have prepared snippets for the large chunks of code. Simply go to the Demos folder for each individual module, and you'll find a snippets file that contain the snippets that I'm using in this course. That's handy if you want to build the application together with me. So now I'm back here in the application, and the first thing I'm going to start doing is creating the correct folders. As mentioned in the slides, I'll need a Models, Controllers, and Views folder. Let me do that very quickly. So there, the default folders have already been created. Well, I have to create some more folders later on, but this will do for now. The first thing I'm going to do is I'm going to create my model classes. The first class I'm going to create is the Pie class. The Pie class has a number of properties that I'm going to paste in using one of the snippets in the snippets text file. As you can see, the Pie class has a PieID, a Name, a ShortDescription, LongDescription, and so on. As you can see, down here at the bottom, it also has a Category property. We haven't created that class yet, so I'll do that next. And again, I'll paste in the properties for the Category class. So now my model, for now, is more or less ready. One thing I want to point your attention to is the virtual keyword here. Don't worry about that just yet. It has to do with Entity Framework, which we'll look at in the next module. I want to manage my Pies, as well as my Categories, through a repository, so I'll start by creating interfaces for the repository for the Pies, and the Categories, first. So I'll add a new interface, IPieRepository. I'll make this an interface, and this interface defines a GetPieById, which is simply a method that will retrieve a Pie based on its ID, as well as an IEnumerable in Pie, Pies, as well PiesOfTheWeek. We'll do the same for the categories, so I also will create an ICategoryRepository interface. Again, change it into an interface, and add this IEnumerable Categories. To make things a bit simpler, I'm going to work with mock versions of the Category and the Pie repositories. We'll change it in the next module, when we'll add Entity Framework. So for now, I'm going to create two mock implementations. Again, in my Models folder, I'll create the MockCategoryRepository. This class, of course, implements the ICategoryRepository. Of course, we'll see that Visual Studio starts complaining because the interface isn't implemented yet, so I'll do that next. Again, I'm using one of the snippets here. As you can see, I'm using some hard coded Categories here. And I'll do the same for the Pies. So I'll add a mock Pie repository, that again, implements the interface, in this case, the IPieRepository. Now let me paste in the implementation, and I will take a look at it. The MockPieRepository is internally making use of the MockCategoryRepository, as you can see here. I've implemented the Pies collection, again, a hard coded list of Pies. I haven't implemented the other ones yet. We'll do that when we create the actual implementation, coming back from the database. For now, this will suffice. These are not just plain classes. ASP.NET Core does not know about them yet, so we'll do that next. We'll make them known with the dependency injection system from ASP.NET Core. To do that, I'll go to my Startup class. In my ConfigureServices method, I have the IServiceCollection here. And that is actually a list of all services that are registered with the dependency injection system. So I'll register my own services here, as well. Basically at this point, everything is considered a service, so my repositories are also going to be seen as a service. So what I'm going to do is, I'm going to write services.AddTransient, and I'm going to specify the interface ICategoryRepository, and the second type parameter will be the concrete implementation, and that is the MockCategoryRepository. The AddTransient method that I'm using here indicates that every time that I invoke an ICategoryRepository, I will get back a new MockCategoryRepository. Of course, I'll do the same thing for the Pies, so I'll register the IPieRepository with the concrete implementation of MockPieRepository. So that's it for my model at this point. The next thing I'll need to do is I'll need to create my controller. Of course, I'll do that in the Controls folder. And I'll go here to add a new item, select ASP NET, and I'll select the new MVC Controller Class. The controller I want to create is the PieController. Typically, in ASP.NET MVC, controllers are suffixed with the word Controller. My controller needs to inherit from the Controller base class that comes with ASP NET Core. By default, a new IActionResult Index is already created. Let's remove that for now. In my Controller, I'll of course make use of the Category and the Pie repositories. So I'll create a private field of both of these. Next, I create the constructor, and to the constructor, I'm going to pass two parameters, an IPieRepository, and an ICategoryRepository. Now through dependency injection, through constructor injection, the ASP.NET Core dependency injection system will give me back an instance, because I've registered those in the startup of my application. I will, of course, save these in these local fields I've created earlier. Now I want to create my first action method. That's the method that that is going to be invoked by MVC. I'll make this a public method, and the return type will be ViewResult. So I basically will be returning a View. I'll call this action method List, because I'll be showing a list of Pies. In the implementation, I'm going to return a View, and that View will actually get back from me some data, and that data is going to be the PieRepository.PiesCollection. That was that IEnumerable that was getting back some hard coded data at this point. Let's compile things to make sure that we haven't made any errors. And that all seems fine. Now of course, I can't run the application just yet. I've just created a controller, but I haven't created any views yet. Let's first go back to the slides, and then we'll come back and add the view.

  20. Creating the View Now that we have everything up until the controller already, it's time to add the view, so that we can actually visualize the data that we've retrieved via our controller. Views are basically HTML templates that will be displayed to the user. In general, we can identify two types of views. The basic one, so let's call it the regular views, and the strongly-typed views. Let's explore these with some samples. What we see here is the most basic view template I can show you, it's plain HTML, as you can probably see, containing a div that will be displaying a static line of text. While this is technically a view, it's not very dynamic. We could just have created a static HTML file here, as well. Of course, views are capable of much more. More on that in just a second. Now this view will be displayed as the result of an action method being invoked. Here's our PieController again. So in the action method, we are returning a ViewResult. Notice the last line here, we are calling the View method. When invoked like this, this will tell MVC to render the default view for this action method. But what is that default view, then? Well, MVC will, by default, search for this default view in a subfolder of the Views folder, with the same name as the controller. So when we are working with the Index method in the PieController, it will search for an IndexView in the Pie subfolder, as you can see here. Now, an error will be thrown if this file can't be found, so that if you want, MVC allows you to override this default behavior, but that is outside of the scope of this course. And in most applications, it's really not required. You should, in fact, be following the conventions as much as possible. Now as mentioned, the view we've just looked at is pretty boring, it's not dynamic at all. Creating dynamic pages is the reason we are using a web application platform, isn't it? And in MVC, it's the job of the controller to construct some data, we've already seen that. This data is then passed to the View, which can now render that data into HTML. And a first, very basic way of passing data from the controller to the view is using something called the ViewBag property, which is part of the controller base class. And the ViewBag property is, in fact, dynamic, meaning that you can assign arbitrary properties, which will then become available in the view. Here in the snippet, you can see some controller code, and in here, I'm using the ViewBag property to pass some data from the controller to the view by assigning a value to the message property. Again, ViewBag is dynamic, so I can assign just any property I want. Now in the view, we are now referring to that value again, loading in the value dynamically in the HTML. The highlighted line we see here is actually a so-called Razor expression. This code is evaluated when MVC is using this view to generate a response. We'll be seeing a lot more Razor code soon. Note that Razor itself hasn't really changed since MVC 5, although some very useful things have been added. I will come across these later in the course. Now although it's possible to pass all the data form the controller to the view using this ViewBag property, it is not very handy in larger applications. There's an easier way, and that's through a strongly typed view. Now in many cases, you'll still use that ViewBag property to pass some extra data, and we'll do that in the demo. Now just to be clear, our markup code, so the view code, will be written using Razor. And Razor is a markup syntax which allows us to include C# code inside our web pages. The code is, of course, executed server side, so it will be ASP.NET Core who's executing the code, and the resulting HTML is sent down to the clients. Now Razor has been in the ASP.NET MVC platform since MVC 3. Let's take a look at how we can create a strongly typed view. Here again is the controller, the PieController, which I've already created. Now in there, I have an action method called List, and it's not just returning a view. Instead, it's returning View, passing in a list of Pies using the Repository property as a parameter. This results, behind the scenes, in this list now being set as the ViewData.Model property of the ViewResult that's being returned. The View does get access to this list now. Let's take a look at the View code. To create a strongly typed view, so at the top, we have to include the type of the object that is going to be passed in. We are doing this using the Razor model keyword, followed by the type, which is in here, IEnumerable in Pies. When the type is in place, we can now access the model, so the data that was passed to the View. What I'm doing here is using Razor code to loop over all the Pies in the model. And so, the model was my List, and I'm using a foreach Razor expression here, which is just a C# expression inside of the HTML. And inside the loop, I'm creating more HTML elements, and again, through Razor expressions, I can now access the properties from each individual item in the list, such as the name of the Pie, the Price, the Category, and so on. Since we had, at the top, declared that the View is typed to IEnumerable in Pies, we will get Intellisense when creating our View code. In the screenshot here, you can see that inside the HTML editing experience, we get access to the properties of the model type, and we'll see this when we create the code in the demo. In many cases, we'll see that the model that we want to pass to the view doesn't map to the domain model. For example, imagine that our view needs to display the list of Pies, but also needs to display the name of the Category that the Pie belongs to. We could use the ViewBag again, in this case, and pass the extra data, so the Category name, using the ViewBag. Now while that works, a much better approach is using a View Model. A View Model is just a class that wraps multiple properties together, so that the View can access all the data it needs. Such a View Model can literally be seen as a model for the view. Here in the snippet, I'm showing one of these ViewModel classes that we will be using in our demos, the PieListViewModel. This class wraps the IEnumerable in Pies, so that's using domain model classes, but it also comes with a string called CurrentCategory. And then we are passing an instance of this type to our strongly typed view.

  21. Demo: Creating Our First View Now it's time to create the first view in the next demo. We are going to apply what we've just learned. I'll bet you're eager to see your hard work in the browser, but in this demo, I'm going to make sure that we actually see what we have done so far. So I'm going to start by creating a View. I've already created the Views folder, and the next thing I'm going to do is I'm going to create a subfolder here, called Pie. That name, of course, isn't random. By default, ASP.NET will search for Views that have to do with the PieController in a subfolder Pie of the Views folder. The next thing I'm going to do is I'm going to create my first View. So I'm going to go here to Add, New Item. I've earlier created an action method with the name List, so I'll need to create a View with the name List, as well. Automatically, when I invoke the List action method, it will return the View, so it will search for the Pie folder, and then in there, the List view. And that's this one. Let's delete what was generated by default here. From now on, just put in some plain HTML. We'll change it in just a second. Now this is, of course, some static HTML, and we want some dynamic pages. What I'm going to do is, I'm going to declare that my view will be showing some Pies. So the model that this view will be getting in is going to be of type IEnumerable in BethanysPieShop.Models.Pie. In the body, I'm going to start writing some basic Razor code, and I'm going to loop over the Pies in my Collection. For that, I'll use the foreach, and note, I've started it with the at symbol. This way, Razor knows that this is actually a Razor expression that is going to follow. foreach, and do a tab, var pie in Model. And Model is known by MVC, it points to the model that this view is bound to. And that's, in this case, the IEnumerable in Pies. In here, I can write just plain HTML, and I can mix that with Razor syntax. For example, I can write an H2 here, and in there, I can write pie. Of course, I need to indicate that it's Razor, so I'll need to prefix it with the at symbol again, and then use, for example, Name. This means that I'm going to display the Name property. I'll do the same for the Price, and format it to my local currency, and I'll use the same for the Category.CategoryName, so I can dig into the different properties, as well. As I'll run this in the browser, and see if we have done everything correctly. By default, you will be getting a 404, Not Found. Did you do anything wrong? Well no, you didn't, but remember that we have created the PieController, and so, we can actually browse to the PieController and then, invoke the List action. We'll talk about routing later in much more detail, but if you want to view our list at this point, we'll have to go to the Pie/List. And there we go, we can actually see our list of pies being displayed. If you've been following along and you see the same, congratulations, your first View in ASP.NET Core MVC is up and running. If I now want to pass some extra data from the controller to the view, I have different options. The simplest one is using the ViewBag. Let me show you, let's go back to the PieController. Imagine that I want to display the Category that these Pies belong to. I can do that using the ViewBag. The ViewBag is a property of my Controller, and it's actually of type dynamic, so I can give it just any property I want. So I can just write ViewBag.CurrentCategory is Cheese Cakes. I can get back that value in my View by simply writing @ViewBag.CurrentCategory. Of course, you won't get any Intellisense here, simply because it's a dynamic. Let's run it again, and we should see that "Cheese cakes" string being shown here. And there we have "Cheese cakes" showing at the top. The ViewBag is an okay way to work, but in many cases, you'll want to work typed as much as possible. So I'm going to remove that again, and I'm going to introduce my own ViewModel. I'll go ahead and create a folder, ViewModels, in my project. In there, I'm going to create my own class, PiesListViewModel, which is going to contain the data for this particular view. It's going to be a model for the view, hence the word ViewModel. Add a new class, and I'll call it PiesListViewModel. It's a very simple class that will contain an IEnumerable in Pies, as well as a string of the current category. Or I can go back to my Controller, and update the List methods. I'm going to create a new PiesListViewModel, and then I'm going to set its properties to the data I need to pass from the Controller to my View. Of course, I now need to pass to my view my PiesListViewModel. Now let's return to the View. My View is not going to be typed to my ViewModel, so I need to update these to point to my ViewModel. My Model is now complaining, as you can see here, because Model is now not a collection any longer. I need to change this so that I'm going to loop through the Pies collection. And of course, I can also access again the current Category, but now, using the @Model.CurrentCategory. That's, again, a Razor expression that will get the current Category from the Model, which is the PiesListViewModel, and I'm passing to my View. Let's run our site again. And there we go, we see the current Category, as well as the List, once more.

  22. Improving the View Code Now that we have our first View, let's take a look at some optimizations we should be doing before continuing. Now in its current state, our application contains just one page, and the final application will have quite a few pages. And in most web pages, there will be a lot of common layout that should not be duplicated across all pages. Think what a nightmare it would become to update all of these. Therefore, most pages are based on a template. In ASP.NET Core MVC, this is supported by creating a Razor layout file. This is effectively a template that multiple of our views, perhaps all of them, will be based on. Since multiple views will be sharing the layout, typically, the layout files are stored in the Views/Shared folder. The Razor engine, when rendering our Views, will search in this location by default. Note that it's possible to create multiple layout files, for example, one for your public pages, and one for your administrator pages. The layout is a special form of view, but in the end, it is just HTML, with some specific Razor expressions in there. Take a look at the code on the slide here. It's plain HTML, and it will typically contain the common layout for all pages. So things like menus should be in here. However, it also needs to include a placeholder, where all the actual content will be placed from our actual view. That's where the RenderBody expression is used for. Razor will know that the contents specified by the action method will need to go in this location. Now of course, our view also needs to indicate that it wants to use a particular template, or a particular layout. We can include the Razor expression you see here on this slide, at the top of our view code. So this will basically say to Razor, "Search for a layout called Layout.cshtml, "and set it as a template for this view." Razor will then search several directories, including the Views shared folder. Now while this works, this would require me to add this expression on top of each of my views. If I now rename my layout, I need to update it in each of my view files, something that I wouldn't be looking forward to doing. We can resolve this by using a so-called ViewStart file. Automatically, when just any view is rendered, Razor will look for a file called _ViewStart.cshtml, and its content is included in the actual view file. So, we can move the setting of the layout of our view into this ViewStart file, and it will automatically be included when the view is rendered. There's one more special file, and this one has been added with ASP.NET Core MVC, the View Imports file. As the name implies, this file is used to include types using an @using statement. These types will then automatically be known when editing the view code. We'll add more code to this View Imports file when we look at the Tag Helpers later in this course.

  23. Demo: Adding a Layout, ViewStart, and ViewImports file In the next demo, I'm going to make some changes to what we've done in the previous demo. We are going to add a Layout file, a ViewStart file, and a ViewImports file. And of course, next we'll update our existing view to use these files. The view that we have created so far contains all the HTML in the view file itself. Of course, if I have a real life application with many views, this is not going to be easy to maintain. So I'm going to do some work to make sure that we're using a template. Let's go to the Views folder, and the first thing I need to do is, I need to create a shared folder in there. The shared folder is a known location that will be searched by default by ASP.NET Core MVC. It will search in there, for example, for layout files, as well as other files that we'll come across. I'll create my layout file, which is my template, by saying Add, New Item, and then selecting, in the ASP.NET node, MVC Layout Page. I'll leave it the default name, _Layout. I'll change the header slightly here, so that we have a hard coded title. Notice the @RenderBody here. That's a Razor expression, it's a placeholder where the actual view content is going to be placed. And I'll need to update my own list. All the HTML code that is surrounding my actual content needs to go away, so let's remove this, as well as the closing body and closing HTML. At this point, my view does not know about the layout that it should be using. I need to point it to my layout file, to my template file, let's say. How am I going to do that? I can do that here, inside of the List.cshtml. Very often, we'll use a ViewStart file for this. The ViewStart file is going to be placed in the root of the Views folder. Again add a new item, select MVC View Start Page here, and leave it the default name, ViewStart. The default generated code automatically already says that the layout for this view should be Layout. So when now, a view is going to be rendered, it is going to search for ViewStart, and when it finds it, it will notice that the layout is pointing to the layout that I've just created. Another general file I can add here is a View Imports page. Again, I'll leave it the default name, and I'll put it in the root of my Views folder, as well. The View Imports file contains, as the name implies, imports, just like we have in C#. So in here, I'll declare some types, which are then known inside of my views. So I'll declare that I'll be using BethanysPieShop.Models, as well as the ViewModels. I can now simplify my list again, into just PiesListViewModel. When we build it, we will see that Visual Studio notices that my PiesListViewModel is now known through the View Imports file. Let's run things once more. And there we go, we see again the same still ugly looking page, but it's now already using the template, so the layout file that I've created.

  24. Adding Styles I think you'll agree with me that while our page is doing its job of showing the list of Pies, it's not looking anything like what I've shown you in the beginning of this module. Well, the reason is simple, we haven't added any styles to our page yet. The layout is based on Bootstrap, a very popular CSS library, and in this last part of this module, I'm going to add Bootstrap to our project, and in the demo, I'm going to add some custom styles here, as well, so that our page will look better. Now being a CSS library, Bootstrap, of course, is a client-side library. In the past, we've used NuGet to manage this type of packages, as well, however, managing client-side libraries in ASP.NET Core MVC projects can be done using another tool called Bower. Bower is an open source tool, not created by Microsoft, and it's very widely supported, and most distribution of client-side libraries is now done using Bower. Microsoft has included, in Visual Studio, support for Bower. Bower works with a file called bower.json. We'll look at this file in just a second, in the demo. For now, remember that this file contains an overview of all client-side packages you'll want to include in your project. Finally, what you'll see is that all packages, and the files that you reference using Bower, will be added to the wwwroot folder, more specifically, to the lib subfolder. As I've already explained, all static contents in an ASP.NET Core MVC project will typically go under that wwwroot folder. This is considered the root of the application.

  25. Demo: Adding Styles In the last demo of this module, we are going to make our page look a lot better. I'm going to start by including a bower.json file, and next, we'll add support for Bootstrap. Our page does not look anything like what I've shown you at the beginning of this module, well let's change that. We'll simply have to add some styles. Our application is heavily relying on Bootstrap, so I'm going to start by including Bootstrap into my project, and I'll be doing that using Bower. To add support for Bower, I'll add a bower.json file. By going to my project and selecting Add, New Item, I can go to Client-side here, and then select the Bower Configuration File. Again, leave the default name to bower.json. This is the default Bower file. In here, I can add dependencies. What I will want is that I'll have support for Bootstrap, so I'll simply type bootstrap, and then the version. The version that you see here is the latest version at the creation time of this course. And now I'm going to save things. You'll notice that, in the Dependencies folder, it starts restoring files. It's actually downloading Bootstrap at this point. When we now explore the wwwroot folder, we'll see, in the lib folder, that Bootstrap has been successfully added, as well as jQuery, because Bootstrap relies on jQuery. To make things a bit nicer, we'll also need some images. I have provided you with the images, and you're going to have to place them in images folder, in this root folder here. So I'm adding a folder, Images, here, and I'll go to the Assets folder in the downloads for this course, and then copy the five images which are in there. You don't need all of them at this point, but you will be needing them later on in the course. Finally, I'm going to create a folder, Content, and in there, I'm going to write my own CSS. In effect, I'm going to be copying some CSS, because that is not the goal of this course. I'm going to add a new CSS file, Style Sheet, and I'm going to call it site.css. If you're following along, simply go to the snippets, where you can copy all the CSS for this course. So here is the CSS, I'm not going to go over the CSS, it's actually an open source template based on Bootstrap. And I'll need to update my template. Let's go to the layout again, and in here, I'm going to paste in some more code, first, I'll add some links to JavaScript and CSS files in the header. The first one is responsible for getting the correct font, the second one is Bootstrap, the third one is actually getting in my own CSS, and the two last ones are actually going to work with jQuery and the JavaScript that is necessary for Bootstrap. Now that I have Bootstrap added, I can actually make things a bit nicer looking. I'm going to paste in another snippet here, that is going to make the layout of my application already a lot better. I'm not going to explaining how Bootstrap works. There are other courses here on Pluralsight that explain you Bootstrap in a lot of detail. The base template has now been updated. I also need to update how an individual Pie will be displayed, let's go to the ListView again, and I'll add some Bootstrap code here, as well. Instead of showing this plain div, I'll replace it with, again, some Bootstrap code. And if we now run things, well then, we should actually be getting a nicer looking page. Let's take a look. And there you go, you see the logo, the background, and the nicely formatted individual Pies being displayed. This already starts looking like the site that we are going to create. And I hope you're happy with the result.

  26. Summary That was quite a long module, but reflect on where we are already. We have our first page ready, and the basic structure for our first ASP.NET Core website is up and running. I think that was well worth the time. In this module, we have implemented the MVC pattern in the ASP.NET way. We have created the first model classes for our application, as well as the first repositories. Remember that these are still containing hard coded data, so there's still some work to be done on these. Then we have created the first controller, and we've added our first view, which of course, makes use of this controller. The circle is complete with that. Next, we have also covered in this module how we should be organizing the different view files. I've shown you how the Layouts template file can be created for use with multiple views within our application. You've also seen why we'll have a View Start and a View Imports file. Also, the required effort wasn't all that big. In the last part of this module, we've really made some impressive changes when we have added the Bootstrap. To add client-side packages, such as Bootstrap, I've used Bower, we'll encounter Bower again later in the course. That's it for this module, I hope to see you again in the next module, when we add support for working with a real database using Entity Framework core. Thanks for watching.

  27. Adding Data with EF Core Module Overview Hello, and welcome again to the Building Your First ASP.Net Core MVC Application Course here on Pluralsight. I'm Gill Cleeren and I have the pleasure to guide you through this module as well. The last module, a pretty long one I must admit, has allowed us to create already one good looking page. However, as you hopefully remember we have built a repository on top of mock data. We have been using a hard coded list of pies to visualize in our view. In this module, we are going to change that. I'll be adding a real database and I'll be making changes to the repository so that it will now use the database as well. For this we will be using the Entity Framework. And since we are working with .NET Core, of course, I will be making use of the Entity Framework Core, also known as EF Core. As always, let's start by taking a look at what we are going to cover in this module. Just as a quick introduction, I'm going to give you the basics of Entity Framework SORM. As well as introduce you to EF Core. So diversion that we will be working with in this course. Next, we will learn how we can add support for EF Core in our application. After this topic we'll have EF Core included as well as made changes to our repository. Our pie overview page will then display the same information as before, but now coming from a database. Finally, we'll learn how we can cope with model changes using migrations as well as how we can load some initial data into our database when starting the application for the very first time.

  28. An Overview of Entity Framework Core So let us start with a brief overview of Entity Framework and the latest version, so EF Core. Even if you're already familiar with Entity Framework, you'll pick up what has been added in this latest version of the framework. Entity Framework is an ORM. An object-relational mapper. An ORM allows us to work with relational data using domain objects. Basically, it removes the need of writing data access code such as ADO.NET. Instead we create a model using code. Entity Framework will take care of the actual data storage and retrieval for us. It also has been open sourced, the latest version. So the version before EF Core in fact was Entity Framework 6. Entity Framework supports a Code-First approach. Code-First means that we first write our modeling code and let Entity Framework create the database model based on a domain model we pass it. Database-First exists up until Entity Framework 6. And it allows us to have a database and based on this Entity Framework will create the entities for us in code. The Code-First approach is most often the preferred way of working, since this way we're not tying ourselves to restrictions implied by the database model. Entity Framework has out of the box support for SQL Server but it can handle different databases as well. Very often LINQ is used to work with the Entity Framework model. To illustrate this Code-First approach, take a look at the slide here. In our code we will be creating the domain model just like we've done so far in this course. The domain model consists out of several POGOs such as the pie class. Typically they don't have to inherit from a base class. When we let Entity Framework to its thing, it will create for us a corresponding table in the database that we specify. The name of the table will correspond to the name of the class, while properties are translated into columns. Of course a database is much more than tables and columns. We will see in our demos how we can, for example, create relations, or make sure that Entity Framework will create a key for a given column. Now at .NET Core we are getting access to a new version of Entity Framework. Entity Framework Core. EF Core is a lightweight and extensible version of the Entity Framework data access technology. This new version is basically version 7. But since it's part of .Net Core it's named EF Core. EF Core not also supports the cross-platform approach of .Net Core, so it's possible to target different platforms with this new version. Currently it's amongst others possible to use EF Core with ASP.NET Core, Windows store, and phone apps. Just like the rest of .Net Core, EF Core is also open-source. It supports working with relational databases such as SQL Server. However, with EF Core we're also getting support for non-relational data stores. Such as Azure Table storage. EF Core only supports the Code-First approach, a Database-First approach won't work. And like just about everything in .Net Core, EF Core is also added to our project using a NuGet package. We'll be adding support for EF Core through NuGet in our application in just a minute. Similar to what we've done with other packages, we'll need to configure it directly in our startup. So that our code can make use of it. If you're already familiar with Entity Framework, you can conclude that not much has changed with this new version of EF Core. However, currently some things previously possible aren't added to EF Core yet. Microsoft is committed to bringing more and more features into EF Core as we go along.

  29. Adding EF Core to Our Application Now that you have some background on Entity Framework and the new EF Core, let's go to the most important part of this module. We'll go ahead and replace the current hard coded list of data in our repository with data coming from a database using EF Core. Since we are working with EF Core, we'll be starting with a domain model. So code first. So far in this course we have already created our modeling code and nothing really has to change there. EF Core's Code-First approach allows us to create a model first and it will create the database as well as the interactions with the database for us. No need to go and create database tables yourself. Also note the virtual category property here. We've touched on the virtual keyword being used here in the previous module. Adding virtual to a navigation property makes this a lazy loaded property. Meaning that the related category will only be loaded the first time that we are accessing the category property. Rather or not you need to create your navigation properties virtual depends on the situation. Lazy loading makes sense for situations where you think that you're not going to be using this property often, or when loading the related data in one go would cost a lot of extra database work behind the scenes. Perhaps, because of a large table being carried. If you think that the related data is probably going to be carried anyway, you can leave out the virtual and load this property eagerly. Now as mentioned, including EF Core requires that we'll add packages to our application again. For this, we'll need to make some changes again to the project.json file like we've done before. On this slide you can see that I've added support for the Microsoft.EntityFrameworkCore.SqlServer and tools package. Well there's actually a third package that I have included here and that is the Microsoft.Extensions.Configuration.Json package. This package will need to read out JSON files when we are reading out the connections to it. And we'll take a look at that in just a second. Also, in the tools block of the project.json file, we'll need to make some changes. The reference to the tools package needs to be added here as well. Once we now save the file again, Razor studio will download the required packages so that we can use them from code. With the packages added we can start adding code. To make working with a database possible, we'll have to add a database context clause. You can think of the database context as the link, the bridge let's say between our code and EF Core. It manages the Entity Objects during the run time of the application. So it will populate objects with data from our database. It will perform changed writing and it will also be responsible for persisting the data back to the database. Here on this slide I'm sharing part of the code of our AppDbContext clause. A context clause should be deriving from DB context. It will typically expose a DB set property for each collection of entities it's exposing. Basically, adding these two properties here will be an indication for EF Core that there will be at this point two tables in our database. A bi table and a category table. These properties will be our access point to the values in these tables. Why we access these properties? Basically we are going to carry their values. Know that at this point, we haven't imported EF Core to the physical database yet. It doesn't know where it needs to go for its data. So let's fix that next by adding a connection string. In a connection string we'll specify the location and the name of the database, as well as information on how we can connect with the database. So, the login information. With regular ASP.Net we're used to working with the REP config an XML based configuration file, where we will store a lot of configuration codes including the connection string. In ASP.Net Core we should now store the connection string in again a JSON based configuration file. This file is called appsettings.json. And it should live in the root of the application typically. Visual Studio comes with a template to create this file, we'll see that in the demo. In this slide here, you can see the contents of this file. It contains the information to connect with the database. Since we are still developing locally, I'm using the local DB option. Local DB is an administration free version of SQL Server. Only containing the basic features, but great for development purposes. Local DB can be installed together with Visual Studio. So there is a chance that you haven't checked this when installing Visual Studio. If that's the case, rerun the setup of Visual Studio and make sure that you have the local DB option checked. Alternatively, if you're not able to do this you can also work with the regular SQL Server database for the remainder of this course. The last step that we'll need to perform before we can start working with our database is some configuration work in the startup clause again. We'll need to read the connection string and we'll need to configure the application so that it can connect with the database. First in the constructor, I'm setting the value of the configuration property. This basically represents an entry point to the configuration data. I'm creating a configuration builder instance and then I'm specifying that the configuration files should be searched for in the current directory. Then, I'm loading the configuration data from individual sources using extension methods such as AddJsonFile, where I then specify my appsettings.json file. This will include my JSON file to be read out for reading settings. And finally I call the build method, which will in turn create a structure of the key value pairs defined in our JSON file. Next the AddDbContext method will add the required services for supporting Entity Framework. It accepts as the type parameter my own AppDbContext clause. Making sure that this clause will be used as the context for database operations. The UseSqlServer method sets up support for storing our data in SQL Server. And it will accept the connection string we've retrieved from the JSON settings. With this added, we are ready to start working with EF Core in our regular codes. In this short snippet here, you can see how I use my context clause to carry the properties defined in there. Since we have defined the category property virtual, we can now specify here that we want this property to be loaded eagerly using the include method. Next I'm specifying a where clause for our query. We are in this case only interested in pies where the IsPieOfTheWeek property is set to true. The context is to be used for querying of data, but it also will come in handy when we want to make changes to our database. For example, inserting data. At this point our application can only visualize the read only list of pies. In the next module, we'll start adding code that will insert and update items in the database as well. Such as orders. You can already preview a snippet of part of that code. Notice is what I'm doing here, I'm creating an OrderDetail instance and then I'm adding them to the OrderDetails property on my context. When I'm done looping all items in the basket, I'm going to commit my changes, using the save changes methods. This will make sure that the list of entities kept in memory by the database context will get synchronized with the database.

  30. Demo: Adding EF Core to Our Application We now know enough about EF Core to start making changes in our application. In this demo we'll first add the Dbcontext, we'll add a real repository that uses this context, and then we'll add all the required configuration to our application code. Let's get started. So in the previous module we ended up with the page that showed the list of pies, but I hope you remember that that list was a hard coded list of pies. So we're now going to add support for reading those pies from a database. After that, I'm going to be using Entity Framework Core. Now to use Entity FrameworkCore, we'll have to add some packages to our application, and I hope you'll remember that you'll have to do that using the project.json file. So here we have again the project.json file and I'm going to start by adding the necessary packages to the dependencies collection. So I'm going to paste in three packages that we'll need to add. The Entity Framework Core SQL Server package is basically the data provider package. That's the one that allows us to work with Entity Framework Core in combination with SQL Server. The EntityFrameworkCore.tools package is a package that adds support for tooling, like the name implies. We'll get support for creating a database, creating migrations, and so on. But we'll take a look at that later in this module. The third one the extensions.configuration.json package is not really necessary for Entity Framework, but it's necessary to read out the configuration string for the database. Also in the tools section I'll need to include the Entity Framework Core Tools. Right now I save everything. Take a look at the Solution Explorer, you will see Visual Studio downloading the added packages. Now it's restoring the packages I've added. The next thing that I'll do, is I'll create a database context that is basically the intermediate between my code and the database. So this has to do with the model, I'll create my context in the models folder. So I go here and I create a new clause. And I'm going to call that clause AppDbContext. In order to be a database context, this clause needs to inhabit from that DB context base clause. This clause actually comes with the Entity Framework Core package. So I'll add the correct using statement. And while we're in it, we'll also create the constructor. The database context, like I said, is really the clause that intermediate between my code and the database. It actually keeps track of all the actions that I'm doing with my data, that is then later on pushed back to my database. Now to do that, per domain clause I want it to manage I will have to create a DB set. I'll create a DB set for my current model clauses, so the pie and the category. So I create a DB set for category and we'll call that categories. And we'll do the same thing for the pies. Now it's quite logical that if I want to work with the database, I'll need a connection string to my database. Typically we would have placed that in the app.config file. In ASP.Net Core that is not the case anymore. We will create a separate JSON file. I go to my project and add another file here. Go to ASP.Net and then select ASP.Net configuration file. And you'll see that by default this file is named appsettings.JSON. And I'll leave that default name. Here's my app settings file as you can see, it automatically creates a connection string for me. I'm going to paste in my own connection string. As you can see here, I'm using local DB and the default connection string that comes with Visual Studio also points me at local DB. Now LocalDB is basically a database for developers. It comes with SQL Server, even with the express edition. It's a minimal install that contains all the necessary files to do everything with SQL Server that the developer typically will need to do. I've just passed the database name and have used trusted connection as well. If you do not have LocalDB installed as mentioned you can install it via the SQL Server set up, or you can of course also use your regular SQL Server instance for this application. So now that we have the connection string, we'll also need a place to read it out. And what other place would be better than the startup? So I'm going to go back to my startup clause. I'll need to do quite a few things to read out that connection string. The first thing I'm going to do, is I'm going to create an IConfigurationRoot instance. The configuration root, as the name implies, basically represents the entry point to the configuration data. I'm going to add a constructor to my startup clause as well. To that constructor I'm going to pass an IhostingEnvironment parameter. The hosting environment basically gives me information about well, the hosting environment. So where my application is running. In here I'm going to instantiate a new configuration builder instance and I'm going to point it using a set base path to the root of my application, I'm then going to point it to the JSON file that contains my app settings. And then I'm going to basically pause at configuration using the Build Method. And that is then going to result in a key value pair collection that was in my app settings file. Including, of course, my connection string. In the configure service, like I've done before, I'm going to register services. So I'm going to register my app DB context. For that I'm going to use services.AddDbContext and I'm going to pass my AddDbContext. It accepts an action parameter and I'm going to paste in a Lamda expression. Using a UseSqlServer method I'm making sure that SQL Server is going to be used. And I'm going to pass it from the configuration root the connection string with the name Default Connection. That was the one that we had here in the app settings file. But at this point I think we can actually start working with Entity Framework. The next thing I'll do is I'll replace my mock repositories with real repositories. Repositories that will use my app DB context. So I'll again go the models folder and create a real pie repository and a real mock repository. Let's start with the pie repository. And again we'll of course let this implement the Ipie repository interface. Now of course my pie repository is going to be using my app DB context. So I'll add a private read only field for that one. Since I have registered my app DB context as a service in my start up, I get in an instance using constructor injection again. So I can pass it here as a *constructor parameter and I save it in the local add DB context field. I'll paste in the rest of the implementation of the pie repository. And I'll add the correct using statements. So what I have here is the IEnumberable in pies. It's actually going to load in all pies and it's going to already include all related categories. I'll do more or less the same with the Pies Of The Week collection, just adding a where statement that is checking if the is Pie Of The Week is true. And to get pie by ID is simply getting a value by ID. I'm going to add very quickly the category repository as well. And I'll show you the result. So here I have the category repository that simply has the categories property, which is going to return a list of all categories from the database. Now in my startup file, I do need to make one more change. Remember that earlier we registered the mock versions. We'll have to change that. So I'm going to remove mock here, and we're going to do the the same thing for the pie repository. And now I'm actually registering the real repositories with my service collection. Now you may be thinking, I haven't changed anything under controller. That is correct. I've used the interfaces here and now I'm getting back to dependency injection the real implementations and not the mocks anymore. If I were to run things now, I don't think we'll see a lot because, well, we haven't created a database yet. Let's go back to the slides and then we'll come back here and actually create the real database.

  31. Database Initialization and Migrations In the last part of this module, we'll take a look at some EF Core related topics. Such as initializing the database from code and database migrations. We'll also fix the problem that we now have in our demos that is that, we have specified the model for the database, but don't have the actual database yet. Let's start this part by looking at the database initialization. In a Code-First approach you will come across situations where we'll want to load some initial data into our database. An easy way to do this in ASP.Net Core is creating a clause which gets info at the startup of the application. So from the configure method in the startup clause. Here, we can check using the context if the database already contains our initial data. If not, we can simply add it and then commit it. I'll show you how we can do this in the next demo. Note that the database initializer methods such as drop create database always and drop create database if model changes, don't exist in EF Core anymore. We'll have to do this ourselves. During the development and maintenance of the application, we'll have to make changes to our model. We can't always know upfront how our applications model will change over time. You may be thinking this will be a problem since we have asked EF Core to create a database based on our model. Well don't fear. EF Core supports something called migrations. Using migrations, EF Core can create a C# clause that contains the sequel commands to update the database to reflect the changes that we have made in the domain model. Again, no manual sequel statements will have to be written to accommodate this. A database migration will also be used for the initial database creation. And that will solve the issue that we had in the previous demo, where we weren't able to create the actual database just yet. Working with migrations is supported through the package manager console. And we'll take a look at this in the next demo.

  32. Demo: Database Initialization and Migrations In the last demo of this module, we'll add database initialization code to load the bias in categories into our database at application start up. Next, I'll make a change the model and use a database migration to reflect this change in my database. So let's now go create that database. To do so, I'm going to go to the package manager console. If you do not see the package manager console, you can open it via view, other windows and then select package manager console over here. At this point you will need to build your application, so I'm going to do that first. So I'm now going to create an initial database migration. This will create code that can create database schema for me. In the package manager console type add migration. Now you do have IntelliSense here, so we're going to do a tap here, it will automatically complete my command. I can't pass in a name, I'm going to give this one the name Initial because it is in fact my initial migration that I am creating here. When this finishes, you'll see the initial migration being created. It is like I said, completely created in code. It creates a table for categories and for pies. With all the properties that I had defined. And so those properties are going to become columns in the actual database. At this point it only created the migration file it hasn't changed the database. So I'll go back here to the package manager console and then I'll say update database. And after a couple of seconds we'll see the done message. Now my database has been created. So now let's run the application and then we'll hopefully see something appear. And as you can see we only see a blank page. Which is actually good news, because it is reading from the database, but of course there's no data in there yet. So I'll do that next. I'm going to create a clause in my models directory that contains the database initialization code. I'll call this clause DB initializer. The DB initializer is just a plain clause that we paste in the code and then I'll show you what is happening in this clause. I've pasted in the clause, of course again this is a snippet that you can use as well if you're following along. The DB initializer clause has just one static method Seed. And it's accepting an IApplicationBuilder and maybe you already recognize that from the start up clause, where in the configure method we also had the IApplicationBuilder parameter. I'm going to use the Application Builder to get through the ApplicationServices.GetRequiredService access to my app DB context instance. I'm then going to check if there's already any categories in my context using this context.Categories.Any and if not I'm going to add all categories. The categories are down here in this dictionary. As you can see this is my initial list of categories. I'm then going to do the same thing for the pies. If there's no pies in there, I'm going to add a range of pies to the context. Finally, and very importantly, I have to do the context.SaveChanges. Which is going to commit the data to the database that lies behind the context. Now I do need to call the DB initializer from the startup. To actually execute this code. This won't be invoked by default. So I'm going to go back to my start up and in the configure method I will call DB initializer.Seed and I'll pass in that Application Builder. Remember that the startup is invoked automatically and so is the configure method. So every time my application my starts my Seed method will be invoked and it will check if the initial data is there or not. Let's run the application now again. And there we go. We again see our pies. Now there actually coming from the database. They have been loaded using Entity Framework Core. If you want to see the local database that was created you can go to the Server Explorer, create a new connection using the connect to database button here, enter its database name localdb/mssqlocaldb and then in here you can enter the name of your database. Or you can also select it of course. We then select it. The connection will appear here in a Server Explorer. And you can actually see the tables in your database. As you can see there's three tables; the pies, the categories, and a third table the EF migrations history which is a table that Entity Framework keeps to keep track of the migrations that it already has performed on your database. You can also go to here and show table data. And there you go, there's the data that we entered using the Seed method.

  33. Summary Let's wrap up with what we have learned in this module. It's pretty clear that EF Core or Entity Framework Core, is the ORM of choice for your new endeavors with ASP.Net Core. There's no doubt about it. We have in this module covered some basic functionality such as querying your database with EF Core. Throughout the next modules we'll again be using EF Core multiple times, and we'll have to make some changes in the model several times as well. EF Core isn't on feature parody with previous versions of the framework. However, as you can see in this module, it's definitely ready for most common cases. We have performed migrations, we have created our first data base from code, and much more. You'll see more features being added to EF Core with future updates. With that our application can now be considered a real application which gets its data from a real database. In the next module we'll be adding quite a lot of functionality and pages to our application. I hope to see you there as well. Thanks for watching.

  34. Designing More Pages Module Overview Hi there! Welcome again to my Pluralsight course, Building Your First ASP.NET Core Web application. I'm Gill Cleeren. And if you have any questions about this course, don't hesitate to contact me via Twitter, or send me an email. In the last module, we have updated our application, so that it's not actually a real database backed by EF Core. But our application is still pretty limited, isn't it? It just contains one single page, the List Overview page. But in this module, I'm going to add quite a bit of functionality and other pages. Fasten your seatbelt, by the end of this module, you'll have a much more extended version of Bethany's Pie Shop ready. Let's dive in. Let me give you an overview of what you'll be learning in this module. We'll start with learning about partial views, and we'll use these in the Pie Overview page. Next, we'll be adding a shopping cart to our site. This means that we'll have to add the Shopping Cart View, but we'll also have to make some model changes using migrations we've already seen in the previous module. Next, I'll introduce you to the new view components in ASP.NET Core. We'll build a view component that works to gather with the shopping cart. And while we're doing that, we'll also add the landing page for the website that uses this view component. Finally, we'll take a look at the creation of a custom tag helper, and we'll use this for the About page.

  35. Updating the List View with Partial Views As mentioned, I'm going to start by teaching you about partial views. And we'll be using this partial view in our Pie Overview page. This will encourage re-use of code. And that is, of course, always a good thing. Imagine that you have two different views in your application. In our case, this can be the list page, where we can see a list of all pies. And, secondly, the Home page, where I show a couple of promoted pies. In both views, I'll need some code to visualize a pie with its image, a short description, and the price, perhaps. If we were to write these two views completely without reusing any code, I will basically be creating the same code twice for the visualization of the pie. That's not good, isn't it? Say, "Hello." to partial views. Partial views are like a fragment of code that I can embed in several views, in several places, let's say, enabling code reuse. A partial view is, again, just a view. Here you can see the code we'll be adding in our demo in just a second. Note that we have typed this view to the Pie type at the top. The rest of the code is just plain Razor code, which will display the image, the price, and the short description of the pie. This code is actually just copied from the list view we have created earlier in this course. Now, of course, we need to update our list view so that it is going to use this partial view rather than the build we already have in there. We already have the foreach look, but its contents is now going to contain a call to a so-called HTML Helper. And that it is HTML partial. This is the first time that we're actually encountering an HTML Helper. The reason that I haven't touched upon them yet is that with the arrival of ASP.NET Core MVC, HTML Helpers are largely being replaced with tag helpers, which we are going to encounter starting later in this module. Just to be clear, an HTML Helper allows us to render HTML in the view, much like a control in web forms. Here, the partial helper will search for the partial view as specified, and it will render its output to this particular place in the view. Note that the second parameters of pie is the pie instance that I will be using as the source object for my partial view. While it's not required, it's common to place your partial views in the shared folder. When Razor encounters the HTML partial helper, it will search by default also in this shared folder. Since the idea of partial views is sharing code between views, the shared folder seems a rather good location for these.

  36. Demo: Updating the List View with Partial Views In the first demo of this module, I'm going to create a partial view, and then will update the pie overview page to use this partial view. So now I'm going to create a partial view. For that I will go to the Views folder. And in there we already have the Shared folder. The Shared folder is going to be searched automatically for views by MVC. And in here I'm going to create my partial view. So I'm going to go here and Add, and New Item again, select MVC View Page. And I'm going to call it Pie Overview Summary. Click Add. And as you can see it is just a plain view file, there's nothing special for these partial views. I'm going to start by specifying the type that I will be using in my partial view. And that will be a pie. So I'll use the @model again and specify the type and it will be Pie. Remember, that I don't need to specify the namespace here, because I already have defined it in my View Input file. In here, I'm going to add some code that I already have in my application. Let's go to the List view again. And let's take this code here. I'm going to take this code and paste it in my partial view. As you can see, Visual Studio is flagging a couple of errors because, of course, I do need to access my model instance using the @Model. So I'll change that very quickly. There we go. That seems to be fine again. Now, of course, I need to use my partial view. So now let's go back to the List view. And in here, I'm going to use an HTML Helper. An HTML Helper is basically a way to invoke a method that returns some HTML. HTML Helpers are not that often used anymore. They are replaced by tag helpers, which we'll explore in the next modules. But to invoke a partial view, we still need to use an HTML Helper. And you will be surprised that this HTML Helper is called Html.Partial. And to partial, I need to specify the name of my partial view, which is in this case PieOverviewSummary. And the second parameter is the object I want to pass to my partial view, and it will in this case be the pie. If you run things now, you should actually see the same result. And there you go, you see exactly the same result, we still have the list of pies showing correctly. Now you may be thinking, "Why did we then create that partial view "if the result is the same?" Well, we can now re-use that partial view on several other views. And code reuse is always, of course, a good thing.

  37. Creating the Shopping Cart A web shop without the actual ability to shop is pretty useless, in my opinion. That's why Bethany has asked us to include the ability for people to have a shopping cart when browsing the different pies in her store. Let's see how we can create this in ASP.NET Core MVC. Adding a shopping cart does require quite some steps. I will take a look at these in much detail in the upcoming demo. If you remember from the very beginning of the course, where I showed you that complete application, we have in the website the ability to add items to the cart, and also view the contents of the cart. To encapsulate all that, we'll have to add several items to our application. We'll have a model, so a repository, and some new domain models. We will also have a dedicated controller, as well as a view where the customers can see the contents of the shopping cart at any given point. We will also somehow need the shopping cart itself. In the implementation that I will create, I'm using the session and the session ID. And I store which item the user has currently in his shopping cart linked to that session ID. That is perhaps not a perfect solution, since session Ids do expire, and they will also expire when the application is restarted on the server. But for the purpose of this course, this will definitely do a job. You're probably getting too_____ used to it by now. Adding support for sessions is against something that isn't enabled by default in our application. And, thus, we need to add some extra packages. Here on this slide, you can see highlighted the packages that you need to add to enable working with sessions in the application. Not only do we need to add those packages to our application, we also need to add some extra services and middleware in the startup class again. First, in the ConfigureServices method, I'm using the AddMemoryCache method, which makes sure that the in-memory cache is enabled. Next, I used the AddSession method, which is required to be able to work with session state. Then in the Configure method, I'm using the UseSession method. That will add middleware that enables session state for my application.

  38. Demo: Creating the Shopping Cart As mentioned, we are going to add the shopping cart in the next demo. We'll need to follow quite a few steps. I'll start with the creation of the model clauses. And then I'll go ahead and show you the shopping cart. I'll need to make the shown changes to the packages and I'll use them in the startup clause as well. We'll have to make some migrations for the database and we'll look at the shopping cart view. Let's get started. So we're now going to create the shopping cart. In this demo, I will again be using quite a few snippets. Remember, that you can also use these snippets. You can find them with the downloads of this course. And I'm going to start by creating the model clause I'll need for my shopping cart. Going to go to the Models folder, and add a new class called Shopping Cart Item. This is class needs a couple of properties, let me paste those in. The way that I'll be storing my shopping cart data is using this shopping cart item class. For each pie that gets added to a shopping cart, I'll create an instance of this shopping cart item. This will create a pie as well as the amount of that particular pie that the use wants to order. Lastly, the shopping cart ID will be used to link it with the ID of the shopping cart. I'll talk about that ID in just a minute. I will only be storing the shopping cart items in the database. So I will need another DbSet to be created here in my AppDbContext. So there we have DbSet ShoppingCartItems being added to the AppDbContext. Well, now they were built first. We've made some changes the AppDbContext, we'll need to reflect those first in the actual database. Like we've done in the previous module, we'll need to create a migration and then call Update-Database. To create a migration, I'll again go to the Package Manager Console, and I'll add Add-Migration, and I'll give it a name, AddShoppingCartItem. Now that migration has been created, I can now call Update-Database. And there we go. So now the database knows about the shopping cart items. And that is, in effect, the only thing I'll be storing in my database for my shopping cart implementation. Now the next thing that we'll need to do is create the shopping cart itself. I'll again go to the models folder, and I'll create the ShoppingCart class. The ShoppingCart class is actually quite a large class. I'm going to paste it in and take you through the code. In a shopping cart, I'll keep track of the shopping cart items that the user currently has selected so that I have this ShoppingCartItems list. The shopping cart is identified by ShoppingCartId, that's of type string. Of course, the shopping cart itself will be using the AppDbContext again. I have a static method GetCart that is returning a ShoppingCart instance and passing the IServiceProvider again that you already know from the Startup class. The way that I'm going to be implementing my shopping cart is using the session ID. To get access to the session, I use services.GetRequiredService, passing in the IHttpContextAccessor, and that gives me access to the context. That, in turn, gives me access to the session. I also use the services dependency injection system to get access to the AppDbContext instance. Then I use the session to see if we already have a Cart ID string on there. If not, I create a new GUID and that will be the CartId. Remember that in your ShoppingCartItem class I had this ShoppingCartId string, and that's, in fact, the session ID that I'll be storing. This basically links the ShoppingCartItems with the ShoppingCartId. Add a stored value of the CartId in this session, and I return a new shopping cart, which contains the AppDbContext and also the contains the ShoppingCartId. That was this, ShoppingCartId. Another method, AddToCart, to which I pass which pie, and the amount of that pie that I want to add to my cart. I don't store pies directly to the database. I'm, in fact, storing shopping cart items. And I'm creating those here. Add then add the newly created shopping cart items to the AppDbContext. Finally, I save the changes to the AppDbContext. Very similarly, I have a RemoveFromCart method. I also have a method that returns me the ShoppingCartItems, as well as a method to clear the cart that removes all the shopping cart items from that cart. And I also have this utility method that calculates the total in my cart. Now in the shopping cart, I am using the session. Now to support session in ASP.NET Core, we, again, will need to add packages. And you already know the drill, I think. We'll go to the project.json file and add the required packages here. The ASP.NET Core session package is basically the middleware for ASP.NET session state, and the ASP.NET Core HTTP Extensions package adds some extension methods, among others, for session state. Let's save the project.json file and let Visual Studio download the correct packages. If added packages, we also are going to need to use them in our application. In the ConfigureServices method, I'll need to do two registrations. The first one, AddSingleton of IHTTPContextorAccessor allows me to work with a context. The second one is using the AddScoped method of services. Now what does AddScoped do? AddScoped will create an object that is associated with a request. It is, however, different between different requests. So when I browse through the site, I will get an instance of the shopping cart. When you browse through the site, you will get another instance of shopping cart. That's what AddScoped is all about. And for that, I'm using the GetCart method that we have just created on the shopping cart. That will then create the shopping cart, if it doesn't exist for my session yet, and store the session ID in the session. Also in the ConfigureServices method, I'll need to configure the ability to work with sessions. For that, I'll need to Memory Cache and Session. This will basically enable working with application session state. In the Configure method, I'll need to add the correct middleware to work with sessions. I'm using the UseSession here. And do notice I'm placing that before the UseMvcWithDefaultRoute, otherwise, it will not work. We're making good progress without shopping cart. The next thing I need to do is creating a controller for the shopping cart. So let's got to the Controllers folder, and we'll add a new controller. The shopping cart controller will use the _pieRepository as well as the _shoppingCart. Both of these will be injected through constructor injection. In the view I'll create in just a second, I will want to display data from the shopping cart, as well as the total. I think that should ring a bell by now. We will want to create another view model. Let's do that next. In the ViewModels folders, I'll create this ShoppingCartViewModel. The ShoppingCartViewModel wraps the total as well as the actual shopping cart. On the ShoppingCartController, I'll need to add a couple of action methods. For now, I'll just show you the index, the other ones, we'll only need later in the course. In the Index method, I'm asking a shopping cart to get all the shopping cart items. In that method, I'll check if I'll already have the shopping cart items. If not, I'll return them from the database. I'll then create a new shoppingCartViewModel that contains a shopping cart, as well as the total, and I'll return that to the View. We've created a controller, the final thing is, of course, creating the View. In the Views folder, let's create another sub-folder called ShoppingCart. In there, I'll create New View. I'll paste in another snippet that contains the View code. This view is now bound to the ShoppingCartViewModel. In here, I'm creating a table with the some Bootstrap classes on there. I'm going to the loop over the ShoppingCartItems in the ShoppingCart. I'm going to add, for each item that I found, a row to the table that contains the amount, the name of the pie, the price, as well as the line total. Finally, at the bottom of the table, I'll create another row that contains the ShoppingCartTotal. Let's do a build to see that everything works. Things are now successfully compiled. However, we can't really see the results of our hard work because it's not possible to add items to the shopping cart at this point. We'll do that in a later demo. As for now, return to the slides.

  39. View Components Now that we have the shopping cart added to the application, I'm going to use a view component to show on each page how many items that we have in our basket. Of course, before we do that, let me show you a bit about what view components are. We have, in the beginning of the module, looked at partial views. Partial views are a very helpful feature of ASP.Net, but they have a limitation, though. Take another look at the partial view code here on the slides. As you can see, it's working on data that is being passed to it from the calling view. In our case, it was the pie overview list. If the partial view would need other data, we could, for example, for the overview list, create a view model that contains the data needed for the partial view or views it's using. Well, that works, but it's not really a perfect way of working. Now ASP.NET Core comes with a new feature that will help solve this, and it's called View Components. A view component is similar to a partial view in many ways. Just like a partial view, a view component is only going to be used to be displaying partial content. You won't be using a view component for the full response. It's a C# class, which provides a partial view with the data it really needs. In the C# code that sits behind the view component, we can then write code that gets the required data from wherever needed. It's not limited to the data that is being passed through it from the calling views. It's following the same separation of concerns as we see between the controller and the view. So even in that view, a view component is a good approach. And, as mentioned, it's not a standalone component, it's always going to be invoked from a parent view. But it can execute code to load data itself. A view component actually consists out of a class and probably also a view that will be shown. First, let's take a look at a class. To create a view component, we have actually three options. Each of them will allow us to create a view component. The first option is creating a class that derives from the ViewComponent base class. Second one is creating a class that is attributed with a ViewComponent attribute. And the third option is simply calling a class of which the name ends in ViewComponent. And if you select this last approach, the suffix is removed to indicate the real name of the component. Whichever approach we use, the ViewComponent class must be a public, non-abstract, nested class, just like a controller. In the sample code you see here, you can see a basic few component class called ShoppingCartSummary, which inherits from the base ViewComponent class. To work as a ViewComponent, the class also needs to contain a method named Invoke. Now the Invoke method will be called automatically when the ViewComponent is used. Here, this will return an IViewComponentResult, passing in a model. The latter can actually be data which is retrieved by invoking some repository, so completely independent from the view that's invoking the ViewComponent. Now we'll see this in action in the upcoming demo. Next to the class, a view component will typically also have a view that is the visual part of the view component. It is not strictly necessary that your view component has a view. It may simply return a string, which is then inserted. However, in most cases, you will have a view. At the view part of the view component, it's typically located in a folder called Components, which is a sub-folder of the Shared folder. Here in this screenshot, you can see that we have a folder called ShoppingCartSummary, which lives in the Components folder. The latter is then itself, a sub-folder of the Shared folder. And in that folder, you'll find, again, cshtml file, which contains the ViewComponents view part. Now when we want to invoke a view component from a view or from a layout, we'll have to use the new Razor @await Component.Invoke expression. When we want to invoke a view component from a view or layout, we'll have to use the new Razor, @await Component.invokeAsync expression. Here you can see this expression. I'm passing it the name of the view component I want to invoke. Of course, without the suffix ViewComponents.

  40. Demo: Creating a Simple View Component Let us now return to our demo. I'll show you briefly the home page, since that is a very simple view. I'll then create a view component, and then I'll add the view component to the layout pages. And, in fact, you'll see the home page, amongst others, then using that view component through the use of the layout. So as set, we are now looking at the already created home page. I've take the liberty to create this page, and I'll show you how it's done in just a second. So, as you can see, we now have this banner, this carousel here at the top. And I have a list of pies of the week, down here at the bottom of the page. Let's take a quick look at how I've created the home page that I just showed you. And then we'll add the view component. I really haven't introduced anything new. So maybe it's a good idea to try and create that home page yourself. But let me show you how I've done it. I have created this HomeController here, with just using the PieRepository. In the Index action method, I'm returning a new homeViewModel, which contains the pies of the week. Here you can see that newly created homeViewModel. When I browse through Home/Index, I will open the Home view. Let's take a look at this Home view. So here in the Views folder, we have the Home folder, and in there, I simply have Index.chtml, which will be invoked when I go to Home/Index. In here, I'm using two partials. The first one is the Carousel. In the Shared folder, I have created Carousel.chtml, that's my partial view. This is in plain Bootstrap code that they'll ask me to flip through the tree images. We've added these images to the Images folder in the Root folder here. Secondly, I'm using the PieOfTheWeekSummary partial view to show all the pies of the week in the HomeViewModel that I'm returning from my controller. Here you can see the PieOfTheWeekSummary partial view, which is very similar to that other partial view that we've already created, the PieOverviewSummary. So now we are going to add the home page a view component. The view component that I'm going to create is going to show the amount of items I currently have in my shopping cart. So I'm going to create a separate view component for that. I'm going to place my view components in sub-folder called Components. We can name this folder whatever we want. We can place our view components wherever we want, but I like to group them in this particular folder here. The view component that's mentioned is going to show a summary of my shopping cart. So I'm going to create a ShoppingCartSummary view component. I'm going to add a new class called ShoppingCartSummary. And the first thing I'm going to do, since this will be your view component, is let this class inherit from ViewComponent. I'll need to add another using statement here. The neat thing about ViewComponent is that we can write code that will be executed when the ViewComponent is showing. So, here, I will be counting the amount of items in the shopping cart, so I probably need a reference to the shopping cart. I have the correct using statement here. I've now created a ShoppingCartSummary constructor, which is getting in, again, through dependency injection, the ShoppingCart. I've registered that earlier in the services collection in the startup. There is one method that will automatically be invoked when my ViewComponent is executing, so when it's displayed on a view, and that is the invoke method. So the code that I write in here will be called automatically. So what will I be doing in this invoke method? I will first invoke again the GetShoppingCartItems method that will make sure that the shopping cart items have been loaded from the database. Then I create a new shoppingCartViewModel, passing in, again, my shopping cart, as well as the total. I then return a view passing to that view, the shoppingCartViewModel that I've just created. The view component is typically a combination of these ViewComponent class, as well as a partial view. So I will now create the view part. While the components classes can be placed just anywhere, we do need to place the view components view part in a specific location. I'll need to create a sub-folder called Components in my Shared folder. And in there, I do get another sub-folder per view component that I'm creating. We've created the ShoppingCartSummary. Well, we'll copy that and we'll create another folder here that has the same name, ShoppingCartSummary. And in there we'll create the view part. So I just create here another view page. I'll name this view Defaul.chtml. This view is now getting from the ViewComponents class a shoppingCartViewModel. So I'll make this typed to the ShoppingCartViewModel class. The ShoppingCartViewModel has the shopping cart, and that has the ShoppingCartItems collection. I'm going to check if there's any items in there. And if so, I'm going to return some HTML. Otherwise, I'm not going to display anything. I'm going to use an icon here, which is coming from the glyph item class in Bootstrap. I'm using the shopping cart glyphicon. And next to that item, I'm going to show the amount of items currently in the shopping cart. We've now created the shopping cart's view component. Let's now use it in the application. The shopping cart summary is typically going to be displayed on each and every page. Wherever I am in the website, I want to know how many items I have in my cart. That calls for a change in the Layout file. I have a snippet here that I'm going to paste in, which contains the navigation bar at the top of the page. We'll create the menu items in here later in the calls, but for now, I am already going to add my view component here. To invoke my view component, I need to write @await and then Component.InvokeAsync, and then the name of the view component, and that was, in my case, ShoppingCartSummary. Let's try running this now. We see the nav bar at the top, but there's no shopping cart summary showing. If you think about it, it's pretty logical, there's no items in my cart yet. Let's go back to the shopping cart summary for a second, and I'm going to add some mock data there. So instead of using the real items, which are coming back from the database, I'm going to write some mock code here. I'm going to, on the fly, create two empty shopping cart items, which are then going to be placed inside of the view model. If we now run the application again, we will hopefully see the view component showing that I have two items in my cart. And there you go. You see the glyph icon of the cart with two next to it.

  41. Creating a Custom Tag Helper The last topic that we will be discussing in this module is tag helpers. More specifically, I'll show you at this point how to create a custom tag helper. We will be coming back to tag helpers quite extensively in the next two modules. And you'll be seeing in those modules many places where tag helpers are useful. However, in this module, I'm going to already show you how you can create one yourself and we'll add it to the About page of Bethany's Pie Shop. Let's take a look. Tag helpers enable server-side C# code to participate in creating and rendering HTML elements in Razor files. They are a new ASP.NET Core MVC feature. Basically, they allow us to execute code based on HTML elements, attributes, or parent tags in the view. MVC Core has built in quite a lot of tag helpers available. For example, for working with forms, we'll be creating the order form later in this course, and I will be using a lot of the built-in tag helpers to do so. Tag helpers are similar to HTML Helpers that were used in previous versions of MVC. The problem with HTML helpers is that the view code, when using them, isn't very close to HTML anymore. And it can be confusing for non-ASP.NET developers on your team. Using tag helpers, we can reduce the explicit transitions between HTML and C# code in our views. Take a look at these HTML Helpers here. As you can see, the code is actually pretty verbose and not always easy to read. Tag helpers will help us to fix this problem. You'll quickly see that tag helpers are much more HTML-friendly. The resulting HTML is also going to be cleaner and easier to read. Here you can see already, a custom made HTML tag helper. Looks much better, doesn't it? Since they are backed by C# code, tag helpers can give us a much better intelliSense experience while coding our views. This is in sharp contrast with HTML helpers are well. And like I've already mentioned, ASP.NET Core MVC comes with a large number of built in tag helpers, which we'll explore later in this course. It's also an extension point, you can create your own tag helpers as well. Creating tag helpers is done in C#. Tag helpers are just classes, and we can places them in our project wherever we want. In order to become a tag helper, a class needs to inherit from the base tag helper class. The name of the tag helper is composed out of the name of the element it works on followed by tag helper. Here, I am creating my own tag helper called EmailTagHelper. Later, in the Razor code, I'll be able to create an element_____ called Email. And our tag helper will also contain a method that we need to override called process. In there, we are going to add the behavioral code for our tag helper. Although we can place these tag helpers wherever we want, it's a good idea to put all your tag helpers in one single location. The reason is that we have to register tag helpers before we can actually use them in our view code. Here you ca see that I'm calling the @addTagHelper expression. This code should be placed in the view itself, it is going to use the tag helpers. However, in many cases, we will placing this in that ViewImports file, since that way, the registration is done once for all views. I will show you this in the demo. Assuming that our tag helper is correctly registered, we'll be able to use it. With a tag helper what's called email tag helper, we'll be able to create in our view the HTML element. Behind the scenes, this will then invoke that process method on our Tag Helper.

  42. Demo: Creating a Custom Tag Helper for the Contact Page Let's return, once again, to the Demo application. I'm going to quickly create the About page. And then we'll create the email tag helper. Finally, we'll be using the tag helper on the About page to allow visitors to contact Bethany via email. Let's take a look. In this demo, I'm going to create my first custom tag helper. I've taken the liberty to already create the Contact page. It's, in fact, a very, very simple page that has just some HTML on there. I'm going to create an email tag helper that I can place on this page that will then generate a link with a mail-to address in there. I'm going to create another folder in my project, which is called TagHelpers. As mentioned, I'm going to create the email tag helper. A tag helper is just a plain class that needs to inherit from the base tag helper class. The name of the tag helper is important. When I create an email tag helper, so Email and then the suffix Taghelper, I can use my tag helper by just writing Email in the Razor code. We'll see that in just a second. Let's first create a code for the tag helper. So my tag helper will generate a link that is going to display some text. And when I click on it, it's going to send an email to a certain email address. So I'll need two properties in here, the email address I want to send the mail to, as well as the content I want my link to display. These values are going to be wrapped in these two properties, Address and Content. Tag helpers have the process method that I'll need to overwrite. This method will be invoked when my tag helper's displayed. So I'm going to overwrite the process method here. In here, I'm going to build up my tag, my email tag, that is. I am going to generate an anchor tag. So the output of this tag helper should be an anchor tag, that is an "a". On that anchor tag, I'm going to add an attribute. So I'm going to use the attribute.SetAttribute method. And I'm going to set the href attribute to mailto, and then the value of the address property that I'll pass in later on. The text content should be set to the Content property. And I'm going to pass the value, too. With these types of code, my tag helper is already defined. The next thing I'm going to do is I'm going to make a small change in my ViewImports file. Typically the ViewImports file is listing namespaces that are going to be known automatically in my views. And what I'm going to do is I'm going to use the @TagHelper method here. And I'm going to pass it the tag helpers I want it to use, that's the first parameter that you see there. As you can notice as well, I'm using a wild card character there that says that all tag helpers within my namespace, BethanysPieShop.TagHelpers, should now be known automatically in my views. The second parameter show BethanysPieShop points to the assembly that contains my tag helpers. It's very well possible in a large project, that you'll have separate assemblies containing multiple tag helpers. Let's save all this. And now let's go back to the view of my Contact page. In my view, I can now use my tag helper. Before you can use it, make sure that you've built your project. Remember that we have created the email tag helper so I'll now be able to use the email tag helper here in my view code. As you can see, IntelliSense is automatically highlighting my tag helper. It's also giving me IntelliSense about the properties that I have defined on my tag helper. So the address should be info@bethanyspieshop. The @ sign has a specific meaning in Razor, so I'll have to escape it by using another @ sign.So Info@@bethanyspieshop.com. Second parameter I required was the content parameter. And I'll specify the value there to be Contact us. Close the tag helper and let's now run it again. Let's go to the Contact page. And here we have the Contact Us link showing. Let me show you the source for this page. Here is the resulting HTML. It generated an anchor tag with an href mailto:info@bethanypieshop, and as content, Contact us. So there you go, you've already created your first custom tag helper, congratulations.

  43. Summary With that, we have reached the end of this module. As always, let's summarize what we have seen in this module. We have started the module by creating a partial view. A partial view is basically a piece of view code that we can re-use across our site, thus preventing us from having duplicate code in our application. We have spent quite some time creating a shopping cart in this module as well. The shopping cart implementation that I have used here is relying on sessions, and so session ID that is stored on the server. Like pretty much everything in ASP.NET Core, we had to include support for sessions using the Project.json file. Next, we have created our first view component. A view component can be seen as a type of partial view. However, as I have explained, in a view component, we're not limited to just using the model that is passed by the surrounding view. We have a created the view component for showing the amount of pies we currently have in our shopping cart. Finally, we've touched for the first time in this course on tag helpers. Tag helpers are one of the most important new features that's come with ASP.NET Core MVC. And we have in this module created the first custom tag helper. We'll be using tag helpers again quite a lot in the upcoming modules. I hope you now feel smarter again. And I hope to see you again the next module, where we will be adding the navigation, allowing us to, well, navigate between the different pages. See you there.

  44. Adding Navigation Module Overview Hello, and welcome to another module in the Building Your First ASP.NET Core Web Application course here on Plural Site. My name is still Gill Cleeren. I think I'm going to keep it like that for the remainder of the course. If you have any questions about this course, please feel free to contact me or post your questions on the discussion board here on the Plural Site website. In the last module, we have been adding quite a few pages, but there was one problem. We can't really navigate between the different pages. Navigation on a website is a pretty common thing. So I guess the time has come to see how we can add navigation to our site. By the end of this module, we'll have a menu in our application that allows us to do navigation from one page to another, and it will also have added navigational elements throughout the pages we have already created. The overview for this module is pretty short. First, I'm going to start by explaining you the most fundamental concepts around ASP.net core MVC's routing. After we've seen the options that the routing engine in ASP.net core MVC is offering us, we'll go ahead and apply this in our application in one large demo.

  45. Routing Fundamentals As mentioned, I'll give you first an overview of the routing engine in ASP.net core MVC and we'll take a look at some samples. With ASP.net WebForms, and also with many other web technologies, there was a relation between a URL and a physical file on the disk. We could send a request to a server, and basically what a server in normal circumstances was doing was looking for the file following the structure of the URL, and returning that file to the client. This file-based way of working worked perfectly in that world. With the dawn of MVC, that file-based relation was not going to work anymore. When a request is now received on a server, what is happening is that an action method part of a controller is going to run and return a response. Although what is being returned in the end is a view, so a file ending in CSHTML, the URL is effectively targeting an action method and not a CSHTML file. To make things work, ASP.net MVC has always had the so-called routing engine on board. This engine will make sure that the URLs are mapped to an action method, and in fact it's allowing us to specify how the corresponding action is going to be retrieved. It's a very powerful system. But in many cases, it does require some up-front thought. Let's see how the routing engine works. Routing is based on routes. Each route is a URL pattern, and that is mapped to a handler. The handler is, in the case of MVC, the action method on the controller. The fact that we can use patterns for our routes means that we don't have to type all the possible routes for our application. What will happen is that the URLs are compared with these patterns. And when a match is found, in fact I should say, when the first match is found, that pattern will be used to trigger the corresponding action. Take a look at this basic router. When we look at this URL, we can see that it's made up out of a number of parts. The host, or bethanyspieshop.com, as well as home and index. These different parts are segments. Typically, the first segment will point to the controller, and the second one to the action. Of course, we have to explain this somehow to the routing engine. It's not something that works by default. We'll have to create a route that says that when a URL with a pattern with two segments is encountered, that will assume that the first one will be the controller, and the second one will be the action. If we now try to navigate to slash home, there will not be a match. The reason is simple, there's no second segment here. Only if we have the matching number of segments will there be a match. If we throw /Home/Index/Pies at it, again, there will not be a match for this pattern. The reason is the same. The number of segments isn't correct, so there will not be a match. The number of segments is clearly one of the most fundamental ways for the routing engine to know if a URL matches a pattern. The routing engine will of course work for incoming URLs. However, it may be less obvious that the routing engine will also be used to create outgoing URLs. Outgoing URLs are the URLs that will be generated as part of the HTML that we are returning to the client. Think for example of a menu with several items in there. These items should also contain a well-formed link so that when we click on them, the URL that will be sent to the routing engine can again be matched with a pattern. To work with a routing engine, we have to pass it these patterns that we have in mind. Passing the engine these patterns is something that we should typically do in the start of class again. More specifically, in the configure method. Let's start creating those routes. If your site is going to be pretty basic, ASP.net core MVC contains a method that automatically configures the routing engine to use the so-called default route. The method is called UseMvcWithDefaultRoute. What this method will do, it will insert MVC in the execution pipeline, and in one go, also configure it to use the route that you can see on the second line of the slide here. This route, so named Default, has a pattern that's very commonly used in MVC. Containing now three segments, and also containing some defaults. We'll take a look at these defaults in just a second. Now, if your site gets a little bit more complex, you won't be getting away with the defaults. Also, most sites will require a number of routes to be configured. In that case, we'll add our own routes. Adding routes is done by passing a Lamda expression per-route that we need to configure. The parameter routes that you see here is of type iRouteBuilder. We define the route we want to create using the MapRoute methods. And to this method, we pass a number of parameters. The first one, name, is pretty easy. It's simply the identification for the route. Sometimes in your code you'll want to explicitly use a specific route. In that case, you should use the route name. Secondly, you'll of course need to pass the pattern. Doing so is done using the tablet parameter. Adding this route will now enable us browse for examples to /Home/Index. Do note however, that with just the route defined as-is, it's not yet possible to browse for the root of the site. So without /Home/Index, let's fix that. If you want to browse to the root, still, an action method on a controller will need to execute. We don't want to force the user to enter these values when just coming to our site. We want to allow the user to browse to bethanyspieshop.com, and arrive on the homepage. The homepage is actually an action on a controller. Namely, for example, the index action on the home controller. To make it possible to make this, and basically use, if nothing, as is specified, we can specify in the route some defaults. Here on the slide, you can see that when creating the route I have specified a default home for the controller, and index for the action. We are doing this using the anonymous type as you can see from the new keyword here. When I now browse to bethanyspieshop.com this action will trigger and I will see content appearing. There's a shorthand available which allows us to pass the default values in line. As you can see on the slide here, I've again specified home as the default for controller, and index as the default for action. Now, however, this approach has a limitation. I can only pass in defaults for the parameters which are part of the template. Also note that with this syntax it's not required to pass defaults for all parameters. Here, I'm just defining a default for the action and so not for the controller. So far, we've only used controller and actions in our routes. Actually, controller and action are the only segments which are known by default to MVC. It is possible to add extra variables. Here in the snippet I've added another variable called id. And I've given it the default value "SomeDefault." I've also passed defaults for the controller as well as for the action. And when this router's now used, the value of the id parameter will be passed to the action parameter with the name id. So if this would be the corresponding action, the value of the id parameter of the route would be passed into the id parameter of this action method you see here. Now, routes have more actions available. It's possible to define a URL segment to be optional. We can make a segment optional by adding a question mark after the name of the segment. You can see in the snippet I've used here that I have defined the id segment now to be optional. This way, a route with just two segments will also match this route since the id segment is now optional. Through the use of what we've seen so far, we can actually make a pattern match a URL with less or more segments in there. It's also possible to check the actual content of the segment. We can put in constraints to restrict just any value turning the URL in a match. You can see an example of this in the slide here. Notice that the last segment I've added colon int. The constraint here is actually the int part. So the part after the colon. With this constraint now in action, there will not be a match if the last segment isn't indeed your value or cannot be passed into one. I've also left the question mark in there meaning that the last segment is in fact still optional. So there will still be a match if we leave that segment out. The last change I will show you to the route is using static segments. Using a static segment in the route basically means that we pull in a segment that is not a variable. Take a look at the snippet here on the slides. Notice that the template is now starting with shop. This pattern will now only return a match if the URL starts with shop. The other two segments still work as before and since they're optional this pattern will result in a match for a URL that simply adds in shop. We've now covered quite a few options to configure routes. This is by no means a complete list of all the options we have with routes, but you've now definitely seen the most important ones. We'll add some patterns later in this module, where we'll be working again on our application. Next to the way of routing that we've looked at so far, which is sometimes referred to as convention-based routing, there's another way of doing routing, and that is called attribute-based routing. With this type of routing, routing works because of attributes that we place on our action methods. It's possible actually to combine the two approaches. For example, take a look at the code you see here on the slides. I've placed a route attribute on there with this value Details is a fixed segment, but controller is a placeholder for the controller name of which this action is part. So assuming that this method is part of the pie controller, if we go to pie/details/2 this pattern would result in a match. Using attribute routing, we can also change, or let's say hide, the original action name. Here, I've again used an attribute, and I have the /All static segment in the route. Normally, this action would be addressable using the /list, but now I'm overriding that, and now this action can be accessed using /All.

  46. Adding Navigation to Our Site We've now covered quite a few things in terms of routing. So the time has come to start adding a good navigation structure to our site. Before I will actually do that, I want to show you one more thing that's very important in the area of navigation. I did already mention that a routing system will actually make sure that outgoing links, so links that are part of the generated HTML code are going to be built up by the routing engine as well. However, it will still be our job to specify which action you want a link to navigate to. So typically, we'll have to specify the controller and the action. In previous versions of MVC, you would typically use the HTML action link to which we pass the controller and the action name as you can see here. I said in a previous module that tag helpers, we're replacing a lot of the HTML helpers in ASP.net core MVC. This new version comes with quite a few built in tag helpers. In order to create a link that takes us to a specific controller and action, we can use one or actually two of these built-in tag helpers. The ASP controller tag helper get as value the name of the controller we're targeting. And the ASP action helper receives the action value. So these two built-in tag helpers are simply helping us with the creation of links. In the next module, we'll be looking at more built-in tag helpers when we explore the creation of order forms.

  47. Demo: Adding Navigation and Routes Now that we are all wizards when it comes to routing and navigation, let's return to Bethany's site. In this demo, we are going to enable routing and configure the different routes. I'm then going to also return to the layout and set up the menu for the site. Finally, we'll also use tag helpers we've just seen to allow us include navigation between the different pages in our site. So far, when we were using the application in the browser, we actually could see pages. So there was already some route active. If I would, for example, go to pie/list, I would get a list of all pies. The reason that this was actually working, was because we added at the very beginning of this course, the UseMvcWithDefaultRoute anywhere. Let's go to the definition of this one. And let's take a look at the comment here. Let's go over here. And you can see that a default route with the following template was added. So the controller defaults to home, the action defaults to index, and the id is optional. If I browse to the root of the application with no controller action or id specified, I will automatically see the home controllers index action. That's what we saw so far. I'm going to replace this. And instead, I'm going to use app.UseMvc(). There's an overload that accepts an action where I can configure my routes. I'm going to do that next. In here, I can now add a new route. Using the routes.MapRoute(). This method now accepts the name of the route as well as the template. So name will be, let's say default. And for a template, I'm going to use, well, let's use a default route again. There we go. Now just using this doesn't really add any extras to my application. I'm going to add another route. But before I do that, I'm going to make a change to my pie controller. I'm going to update the list method, so it accepts a parameter. Let's call this parameter category. Instead of using this hard-coded category that we've been using so far, I'm going to update the code here as well, and paste in another snippet. I'm going to check if the passed in category is null or empty and if so, I'm going to return all pies and set the current category to all pies. If not, I'm going to filter the pies that have the category that was passed in. And I'm going to return that data in a PiesListViewModel again. Let's save that. And go back to the startup file. Let's now add another route. It's very important that we think of the sequence that we put our routes in the UseMvc method here. In general, we'll have to put the more specific routes more to the top because as soon as a match is found it will use that particular route. I've added another route here. I've given it a name categoryfilter, and take a look at the template. The template now contains a static part, pie, then there's the action, and then an optional category parameter. I've also passed in some defaults. The control of it should be used as the pie controller and the action is list. If we look at this list action method in the pie controller, we will be able to use that route that we've just added to invoke this action and we can optionally pass in a category. Let us test our new route. We're still arriving on the home page. So the home controller with the index action is still reachable. That's good news. If I now paste in /Pie/List/Cheese cakes, I will now invoke the list action method passing in the category cheese cakes, and the filtered list is being returned. That's what we wanted. For the second route that we added, it is also doing its job. And the next thing I want to do is to complete the menu at the top. I'm going to fast forward a little bit, and then show you what I've added. I have added a couple of items that I'll show you in the next couple of minutes. Let us now continue by completing the navigation for our site. The first thing I'll do is I'll go to my view imports file, and I'll add support for all the built-in tag helpers that come with the ASP.net core MVC framework. I'm using the asterisk here to indicate that I want to include all tag helpers in the Microsoft ASP.net core MVC tag helpers assembly. So now I can use those throughout all my views. For example, let's go to the shared pie overview summary. When I click on the anchor tag that contains the name, I'll want to navigate to the details action on the pie controller. And I'll need to pass in the id of the selected pie. I'll use for that the ASP controller tag helper. And you'll notice that intelliSense knows about this tag helper since it's highlighting it. I've set this to pie. I'll do the same for the ASP action. And I'll set that to details. And finally, I'll use the asp-route-id tag helper to pass in the parameter value and that will be pie id. So I'll use @Model.PieId. I'll also add the AddToCart button. I've used this
    here within there a paragraph, and in there an anchor tag. I've used a Bootstrap class to make this look like a button. The controller points to the ShoppingCart controller, the ASP action points to the AddToShoppingCart action method and again, I'll pass in a parameter PieId______. This will point to the AddToShoppingCart method that I've added earlier to the ShoppingCart controller. It accepts, indeed, the PieId______. It will let us search for the pie using the pie repository and add it to my shopping cart. I will then be redirected to the next action. I'll copy all this code to my other partial view, the PieOfTheWeekSummary. The next thing I'll do is I'll complete a menu of my application. The menu is of course located in the layout file. We've added the navbar already. In here, I'll add my Home link, that's another link with some tag helpers in there. And I will do the same for the Contact Us link. And that one is pointing us to the index action on the Contact controller that we've already added as well. Now I have done a small fast forward earlier in this demo, and that was because I've added another view component. Let me show you that view component very quickly. In my components folder, I've added this category menu. This one is actually going to ask the category repository for all categories and is returning that to the view. The corresponding view can be found in the components category menu sub-folder. And in here, I'm looking over all categories. And I'm adding an anchor tag in there as well. I'm again using my tag helper's ASP controller, ASP action, and ASP route with the parameter "category". Finally, I'll also add another
  48. that points to all pies. In my layout, I've now added one more line here that is invoking my category menu so the view component like you've done before. As I run the application again, and there's our menu. There's also a pop-out menu. I will be seeing all the pies with the corresponding category, or I can also ask to view all pies. I can now click on one of the pies, and I will be seeing the detailed page. I can also here click on add to cart and this pie will now be added to my cart. Notice that our shopping cart is now working fine as well. We see one item in the cart, and we also see the shopping cart summary showing that I now have one item in my cart. I think we can be very happy at this point. We now have a fully-functioning website, built entirely with ASP.net core MVC.

  49. Summary This module was very welcome I think. It allows us to navigate between the different pages we have so far created in this course, making our site much easier to work with. Let us quickly summarize what we have looked at in this module. We have started by exploring the routing system that comes with ASP.net core MVC. I've removed the built-in routing system that was in my start-up class until now. And I've replaced it with routes I've now defined myself. We've also added more navigational concepts in the application. To allow ASP.net core MVC to create links, we have used the built-in tag helpers. I hope you'll agree with me that tag helpers really help us with the creation of clean HTML. That's all I have for this module. In the next module, we'll take a look at how we can create a form to place orders in Bethany's pie shop. Thanks for watching.

  50. Ordering with the Form Module Overview Hi there, and good to see you back here for yet another module of the Building Your First ASP.NET Core Web Application here on Pluralsight. Our site is not looking great. At the end of the last module, we've included navigation and a menu, and it's now starting to look like a real site. I'm pretty happy already with the result, and if you've been following along, I hope you are happy too. In this module, we are going to be focusing on just one screen, the order form. That intention probably was already clear to you when you looked at the title of this module. Let's start by taking a look at the overview of this module and what you will be learning. The order form is quite logically a form. With the dawn of ASP.NET MVC Core, a lot of novelties were introduced that we can use in combination with HTML forms. And in that area, I'm talking about tag helpers. I wasn't lying when I said that tag helpers were an important asset in the newer version of ASP.NET, and this is already the third time that we're encountering them in this course. So, I hope you believe me now. When we will have created the form, we'll also look at how we can add validation to the model and we'll see how we can improve the form so that the validation rules will kick in when the user has entered invalid data.

  51. Using Tag Helpers to Create the Form Let's kick off the module by exploring tag helpers in more detail. The result of this part of the module will be a working order form, so it will be possible to place an order in Bethany's web shop. How sweet is that? As said, we've come across tag helpers quite a few times already. Just as a small recap, let's take another look at what exactly tag helpers are, and why they are such an important feature in ASP.NET Core MVC. Tag helpers allow our ASP.NET Core MVC service site code to participate in the creation and the rendering of HTML elements in our Razor files. Using tag helpers, we can trigger the execution of code from our Razor files, which we'll have an influent of course, on how the final HTML will be rendered. ASP.NET Core MVC comes with a number, actually quite a large number of tag helpers built in, but as we've already seen, tag helpers can also be created from scratch. In many occasions, they will replace HTML helpers, which were available in previous versions of MVC. For us, as developers, using tag helpers makes the HTML much cleaner compared to what we've had with HTML helpers. Do note though, that not all HTML helpers are replaced with a tag helper. In the slide, you can see here the tag helper that we've already created earlier in this course, as well as the resulting HTML. As you can see, the tag helper blends nicely into the HTML. Let's explore tag helpers in more detail now. ASP.NET Core MVC comes set with a number of built-in tag helpers, and we'll be using quite a few of these in the upcoming demo when we create our form. The form tag helper will allow us to create forms. I think you had figured that out yourself. The input tag helper will, of course, be used to create the input tag. We're also getting from ASP.NET a label tag helper, a textarea tag helper, and a select tag helper. There's also a number of tag helpers which all relate to validation in forms, and we will explore those later in this module. Let's take a look at the most basic, or should I say boring, tag helper. The label tag helper. It's use is generating a label for a property on our model object. To indicate which property it should work with, we get the asp-for attribute, which will get, as value, the name of the property we'll want to display. We have this code in our Razor view. This will result in the following HTML being generated. The value of the generated for attribute matches the name of the property that we've given it. The content of the label displays the name of the property. We can add attributes to our model properties to change the displayed value so that the value will be more readable, as you can see here. If I would be adding other attributes, such as style attributes, this is added to the generated HTML, as you can see here. (mumbling) also works when we work with tag helpers. Of course, only when we are creating a strongly typed view. So, meaning that visual studio knows which type we are binding to. Tag helpers don't only work with just regular elements. Some tag helpers are attributes that you can use on other tag helpers. The form tag helper has itself quite a few attribute tag helpers. Tag helpers don't only appear just as a regular element. Some tag helpers are attributes that we can use in combination with other tag helpers. The asp-controller tag helper can be used on a form tag helper, for example, to indicate which controller should be targeted by the post action of the form. We've already come across this tag helper earlier in this course when we added the add to basket button. Similarly, the asp-action tag helper allows us to specify the action on the controller we'll want to invoke. You've also already seen that we can create a route, where extra parameters are required. To cover for this, we have the asp-route-* where the star can be replaced with the name of the parameter we want to specify the value for. There's also an asp-route tag helper which allows us to indicate which name route we'll want to use. The asp-antiforgery tag helper allows us to counter cross-site request forgery attacks on the site by generating a hidden field called request verification token. We'll see this in the demo as well. Here we can see the form tag helper with some extra tag helpers added. The asp-action is specified. It will trigger the checkout action, in this case, on the current controller, since no other controller has been specified. We've also used the asp-antiforgery tag helper and set it to true. Don't think that tag helpers are limited to just form elements. Definitely not. We've already used tag helpers earlier in this course on anchor elements. ASP.NET Core MVC comes with an image tag helper built in, which has the ability built in to automatically imprint a version tag to the image file part. This prevents the image from being used from cache. Tag helpers also exist to add CSS and JavaScript files. Here we can see an example of a link tag helper. It allows me to use the asp-href-include, where I can then pass the URL of the CSS file. This is useful, since it will accept a wild card here. If I now update the version of the CSS file I'm using, I don't have to manually update the HTML every time, and that is a real time saver.

  52. Demo: Creating the Order Form Now that you have a good understanding of tag helpers that shape with ASP.NET Core MVC, let's return to the demo. We are going to add support for creating orders in the application. I'll quickly show you the order controller and the related domain classes. Then we'll create the order form using several tag helpers. We will also make sure that the navigation to our order form is correctly wired up. Let us now create our order form. I've already created a couple of classes, and I'm going to show you those first. Again, if you're following along, these are available in the snippets for this module. I've created the order class, which contains some basic properties. Each order does have a list of order lines, and these are of type OrderDetail. The OrderDetail class I've also created as well. It contains the forward key to the order, that is the order ID, the pie, as well as the amount that I'm ordering of the particular pie, the price, and then also again some virtual properties to make sure that entity framework core is happy. In my MDB context, I have created two more DB sets, Orders and OrderDetails. I've compiled the application, and I've then added an auto migration, and I've done an update database. I've compiled the application, and I've executed the add migration command as well as the update database command. If you're following along, make sure that you execute these commands as well. I've also taken the liberty to already create the IOrderRepository, which has just one method create. Order, as accepting an order. I've also already created the OrderRepository class, which is using the shopping cart and the MDB context, and implements, of course, the CreateOrder method. In here, I'm adding the order to the MDB context orders, and then I'm looping over all shopping cart items. For each item in the shopping cart, I then create a new OrderDetail and I add those to the OrderDetails collection on the MDB context. Finally, I call these SafeChanges on the MDB context to commit the data to the database. The last thing I've done here is registering the OrderRepository with the Dependency Injection container. Since we are planning to create the order screen, I'll of course need another controller. In the controls folder, I'll add the OrderController. And the OrderController is using the OrderRepository as well as the ShoppingCart class. I'm going to rename the index method into checkout, as that will be the action that I'm using here. It is simply, at this point, going to return the view. I'll create the corresponding view in the views folder. I create the order folder, and in here, I'll create another new view, which is called checkout. It is, of course, the same the name as the action that we've created on the controller. This view will be typed to the order model. Since the user will be entering data, I'll need to create an HTML form. The form tag helper is using the asp-action tag helper that is pointing to the checkout action method. The method is set to post. I'm then going to create a form by adding a couple of divs. In this div, I'm creating, first, a label that has the asp-for tag helper set to LastName. LastName is a property here on my order class. Then, I'm using an input that is also setting the asp-for to LastName. The asp-for tag helper is basically going to extract the name of the property on my order class. At this point, this will still be a last name, but we'll change that later in this module. After, I base it in all other input fields and then labels. All of these are mapping to properties on my order model. I'm also going to add a button here. It's simply an input with the time set to submit and the value to complete order. The form is ready for now. There's one thing I need to do, and that is making sure that I can navigate from the shopping cart to the checkout page. Down here, below this table, I'll paste in another link that is going to invoke the action checkout on the order controller. That is the one that we've just created. Let's run the application again. I'll add another pie to my cart, and then go to checkout now. As you can see, the labels are just using the property names and that's not very clean. I'll need to make some changes to my model to make sure that my form looks better. Let's go back to the slides.

  53. Adding Validation I'm pretty happy about the order form that we have created so far. Although it works nicely at this point, I don't think Bethany will be extremely happy though. It's possible for everyone to just enter incorrect data or even skip several fields. I believe that many orders won't be correctly delivered. To solve this, I'm going to add validation so that we can be sure that the data we'll be receiving is correctly formatted. Before we look at how we can control the validation process, we have to take a look at how ASP.NET Core MVC will match the data coming from the HTTP request with the arguments that are action method needs. This process is called model binding. Using model binding, the objects which are required as input parameters for action methods are created based on the data retrieved from the HTTP request. Imagine that we have an action method that requires an ID of type int s parameter. MVC needs a value to be in there in order to be able to call this method. The process called model binding will try to find a value for this ID parameter. When we do a request for /pie/detail/1 we actually want the one to go into the ID field. Model binding will do this for us. Now, for this purpose, it will use model binders. Model binders are components which will help providing the values from a certain location in the request. For example, there's a model binder that will search in the form data of the request. Another model binder will search the route variables. The third one will search in the query stream. This list of model binders will actually be invoked in this order, and as soon as a match is found, the process will stop and pass the value to our action method. Imagine that we have a route where we have segment ID defined. In this case, the value will come from the route variable and the model binder can provide us with the correct value. Model binding not only works for simple values, but it also works for complex types, such as an entire object. In this case, the model binding agent will look at the target's object properties and it will search for these instead. Again, using the model binding. Imagine that we are creating an order, so we'll be passing several values from the client side such as order ID, total and so on. Model binding will do it best to find all values and create for us the target object, so in this case, model binding will search the incoming values for the properties it needs to create the order instance. If all of Bethany's shoppers would be entering the correct data in the form, the world would be a better place. However, I strongly believe that that won't be happening any time soon. So, we should be validating the data coming from the client. We'll need to perform validation of the data where we are making sure that the data being sent can be used for binding it to the model we are expecting. If that is not the case, we will need to provide meaningful error messages. Now, ASP.NET Core MVC's model binding engine can perform a check to see if the values provided by the model binder meet the requirements of the model object. We can do this using an explicit call in the action method to ModelState.IsValid. This will return to true if the model object has no validation errors and faults, of course, if it has any. Only when the model is valid will it be saving the order to the database, and then we will be redirecting the user. In this case, we will redirect the user to the checkout completed page. If, however, the ModelState.IsValid returns false, we are returning view. Something is wrong with the validation, and so the default view, the same view, is returned so that the user can try fixing any validation errors. Model validation can be done on the entire object instance in one go using the ModelState.IsValid property. This will perform validation on all properties of the object. We also have on ModelState the GetValidationState method, which accepts just a single parameter. This way, we can probe a property to see if it's valid. Finally, we also have the AddModelError method. If we are performing any manual validation rules, we can also manually add model errors when needed, and this method can be used for exactly that purpose. By default, the validation that will be done is pretty basic. Typically, we'll want to add more validation rules on our domain models. For this, we can use the metadata in the form of attributes that we can add on the properties of our model clauses. These attributes allow us to add validation rules directly on the model properties. Quite a few properties are built into ASP.NET Core MVC, including properties where we can specify that a property is required and we can specify constraints for the value, or check a regular expression. It's also possible to create custom attributes, and apply these on the properties. However, you won't be doing that in this course. Let's take a look at the most important validation attributes that we have. Adding the required attribute will raise an error if the value isn't provided. If we require in the form that, for example, the email field is required, we'll add this attribute on the email property. The StringLength attribute allows us to add a maximum, and also optionally a minimum amount of characters that is allowed for the value. If you want to make sure that the length of a field provided isn't longer than what the database can store, we can use this attribute. The range attribute can be used to make sure that the numeric value is within a certain range. To the RegularExpression attribute, it can specify a regular expression, which will be matched by the value of the property. If there's no match, an error will be raised. Finally, the DataType attribute and it's possible values can be used to ensure that the entered value is of a specific type, such a phone number, email or URL. In the code you see here on this slide, we can see a number of attributes being used on some of the properties of the order model class. Required attribute is applied, and an error message parameter is provided. In there, we specify the error that we'll want to display. I'll show you in a second where we are going to visualize all this. The string length attribute is also used here to make sure that the value won't be longer than 50 characters. On the phone number property, I'm also making use of the phone number data type. This will ensure that the entered value is following a certain pattern to match a phone number. We've now seen that using attributes, we can effectively specify custom error messages. These error messages can be displayed inside a validation summary. This validation summary is, again, surprise surprise, a tag helper. In this case, the clause behind the tag helper, the validation summary tag helper, will search for the asp-validation-summary attribute on divs. Any errors that have been found in the action methods will be shown in the validation summary. Here you can see the asp-validation-summary attribute being placed on a div. As value, I've specified all, which will, quite logically, display all validation errors that happen.

  54. Demo: Validating the Form You've now covered more than enough about the validation process in ASP.NET Core MVC. In the last demo of this module, I'll add validation rules on my domain model classes, and then, we'll update the order form to include a validation summary, so that all errors are shown inside a div. Now, here back in the order class, I'm going to start adding attributes on my different properties. Some of these attributes will be useful for validation. Others will be used to make sure that my form looks better. For example, let's take a look at the FirstName property. I'm adding the display attribute here. Adding the correct using statement first. The display property accepts a string that will be picked up by the asp-for tag helper in my form. When I now run the form, it's not going to be using FirstName anymore, it's going to use first space name. For validation purposes, I'll also specify that the first name should not be longer than 50 characters using a StringLength attribute. Using the required attribute, I'll make sure that the value is provided. If not, the error message, please enter your first name, will be returned. I'm going to paste in the complete order class with all attributes, and I'll point out all the interesting other attributes. The BindNever attribute specifies that this value should not be part of the model binding. The DataType.PhoneNumber is also being used here on the PhoneNumber property. Note that the DataType.PhoneNumbr does not apply validation. If you want to validate that this is a correctly formatted phone number, we need to add a regular expression. I am using the RegularExpression attribute here on the email, passing in a RegEx that is checking if the email is valid. Let's go back to our view. I need to display validation errors here. I can use for that the validation summary. Creating a validation summary can be done using a tag helper, the asp-validation-summary tag helper. As you can see from the hint here, the value can be set to all, ModelOnly, or none. If you use none, none of the validation errors will be displayed. If you set it to all, all model validation errors are going to be displayed. That's exactly what I want here. The summary will display all validation errors at the top. While that is an okay experience, it's not a great one. We'll probably also want to display the validation errors where they are occurring. For that I can use the asp-validation-for tag helper. I place this inside of a span, right next to the input where the validation error needs to be shown. Let me do that for the entire form. Now I've created the form successfully, but now I also need to capture the order data. Let's return to the order controller to do that. I'll create another method called checkout, which is now accepting an order instance. How can ASP.NET now distinguish between these two checkout methods? Well, this second checkout method will only need to be invoked when a post is recurring. I'll attribute this with the HTTP post attribute. When a get occurs, this one will be called. When a post occurs, this one will be called. Model binding is going to its utter best to capture all the form input and create for us an order instance. I've pasted in the code here for the checkout method. First, I'm checking if there's any items in the cart. If that is not the case, I'm adding a model error, saying that the cart is empty, and we need to add some pies first. If, however, the model is valid, then I'm going to ask the OrderRepository to create the order based on the values created by the model binder. I'm clearing my cart, and then I'm redirecting using RedirectToAction to CheckoutComplete. If any validation errors are occurring however, then the same view will be returned and validation errors will be displayed. I'm going to add very quickly the CheckoutComplete action here which is simply going to specify a value in the view bank. I'll then quickly create that view as well. Go to the order folder here in under views, and create a new view, CheckoutComplete, and that will just display that message inside of an h1. Let's now run the application again. I'll start by adding a pie to my cart. I'll click on the checkout now button. I'll enter my data. I've now entered some data, and as you can probably see, the form isn't correct yet. I'll try completing the order, and now my validation messages are appearing. It asks me to enter my country, my phone number, and it also mentions that the email address isn't correct. I'll add Belgium here, I'll add a phone number, and I'll complete the email address as well. Let's now click on complete order again, and I've placed a red point here in the checkout action. Let's take a look at the order, and as you can see, all the data that I've entered is shown correctly here. That's the model binding that did its job for us. As you can see, the order has now successfully gone through. We'll be able to enjoy our pies very soon. That completes the order scenario as well. We're almost ready with our site.

  55. Summary The order functionality is now included in our site. It's now possible to add items to the basket, and then place the order using the form that we have created in this module. Again, we've been relying heavily on tag helpers to create the form and its fields, and again, the HTML that we have created was very clean, thanks to tag helpers. We've also added some rather basic validation on the form. Although for many scenarios, this will definitely be more than enough. We've added the validation through the use of attributes that we've added directly onto our model classes. That wraps up this module. I hope you're happy with the result again, and I hope to see you again in the next module, where we will be adding client-side functionality using jQuery. Thanks for watching.

  56. Adding Client-side Functionality Module Overview Hello, and welcome again to this Building Your First ASP.NET Core Web Application course. I'm Gill Cleeren. That's still the same as it was in the last module. We have now already a nicely implemented server-side functionality in our web application. The site looks great already. In this module, we are going to switch gears a bit. I'm going to show you how we can in ASP.NET core, MVC, work with client-side functionality. We'll be calling server-side functionality from the client side, and to do that, we'll have to make some changes on the server side, as well. Let's start the module again by taking a look at what you will be learning in this module. Doing client-side stuff in ASP.NET core will typically require that we'll be using some client-side libraries, such as jQuery. That's exactly what we'll be doing in the first part of this module. I'll be showing you the best way to add libraries to our project, and we'll again be using Bower. When we have added a library through Bower, and that'll be jQuery by the way, we'll also need to be able to invoke an action method from the client-side code. In the second part of this module, I'll be showing you how we can create an API controller, which doesn't return HTML, but instead, returns data in the form of JSON. After finishing this module, you will have seen how to make your site more interactive and responsive through client-side scripts and an API controller. Let's get started.

  57. Adding Client-side Libraries with Bower So first as said, I'm going to be adding a client-side library to my project. This library will be sent to the client, and it will, of course, execute on the user's machine. You've already done that earlier in this course when we added the Bootstrap package to add styling support for our site. We've been using Bower before, which is, starting with ASP.NET core MVC, Microsoft's preferred way of working with client-side packages. Previously, we used NuGet for this as well, and although that still works, Microsoft is pushing the open-source tool Bower to do this. Let's see how we can add support for jQuery to our site. To work with Bower, and thus to manage the client-side scripting libraries that we'll want to use, we'll need the bower.json file in our project. If you have been following along with this course, this file should already be in the root project as you can see here in this screenshot. We can work with the bower.json file directly, so editing the JSON code manually. We've already done that when we were adding support for Bootstrap earlier in this course. Alternatively, when we right-click on the project node, we'll get an option to Manage Bower Packages. This is an option which is pretty familiar to working with NuGet. Selecting this option in the menu opens this dialog you can see here on the slide. Again, very similar to NuGet's package manager window, we have the ability to search for packages, see the installed packages, as well as which of the installed packages can be updated. Selecting a package also gives you an option to choose between the latest version or a previous version. The latter could be needed if you have another dependency that requires a specific version of a library, for example. All changes that we make in the window that we've just seen are reflected in the bower.json file. As mentioned, we can also directly edit this .json file, and when we save the file, the client-side packages will be downloaded or updated where needed. Here on the slide, we can see the result of adding jQuery to our site. In this case, I've added version 3.1.1, which is the latest version at the time of the creation of this course. All packages that we are adding this way will be downloaded to the wwwroot/lib folder. Remember that by default in ASP.NET core, the wwwroot in our project refers to the root of the application. All static files, such as javascript or css files, should go in this folder. In the screenshot on the slide here, you can see that the jQuery library was successfully added to the project. Now with jQuery added, we can now add support for using jQuery in our application. Adding scripts can be done in several ways. Typically, scripts which are going to be used in several places throughout the application will be included in every page. When we want to do that, the layout file is a good place to start. As you can see here, I've added a script tag in the head of the layout file, which is, in this case, pointing to the jquery.js file. Alternatively, if we think that it's better that we let the individual pages decide to include scripts, we can use the RenderSection method. Using RenderSection, it becomes possible for you to inject a section into the layout. When Razor encounters the RenderSection method, it will replace it with the contents of that section in the view. Notice the second parameter, which is set to false. This means that the views that will be using this layout can include this section, but they are not required to do so. If you set it to true, all views that omit this section will result in an error. Which option you'll want to use here depends on what you'll want to achieve. If you want all views to really include the script section, you'll set this to true. In the views using this layout then, we can now include a script section. Note that the name scripts is the same as in the layout file. So that is just the ID of the section. This has to be exactly the same in two locations. Also note here, that script is not a keyword. You can name this section in any way you want, and now, within this section, we can include our own script code, or we could possibly include other javascript files, which will then be added to this page.

  58. Demo: Adding jQuery to Our Site Let us now return to the demo, and we'll add support for jQuery in our site, using Bower. We'll also include jQuery in the layout file, so that all pages will know about jQuery. So let me show you how we can manage client-side packages using Bower. If you look at your solution, you may not be able to see the bower.json file. If that is the case, click here on the Show All Files button, and the bower.json file will appear. We've added it already earlier in this course, and you see my current bower.json file. We can edit the dependencies directly in this JSON file, or you can also right-click the bower.json file and click on Manage Bower Packages. This opens an interface which is pretty similar to what we get with NuGet. I will add packages here directly in my bower.json file. Now what I'll be adding is jQuery. Now we have, in fact, already support for jQuery in our application, which came because it's a dependency of Bootstrap, but I'll add the latest version of jQuery here manually as well. To do that, I write jquery and then the current version, which is 3.1.1, and I save the bower.json file and automatically, all the client-side packages are going to be installed. As you can see, there's not a lot of difference. jQuery was already there because it's a dependency of Bootstrap itself. If you want to add other client-side packages, this is the way to do it. As you probably also remember, we've added support for jQuery in our layout file. Here you can see the reference to the jQuery library. I've added jQuery here in the layout file so that all my pages that use this template will be able to use jQuery without adding any custom script references. Now I'm going to add the @RenderSection here, passing in the name scripts, and then the required parameter is set to false. By adding this @RenderSection expression, I'm indicating that my pages that are using this layout, so in fact all my pages, can add another section named scripts, and that will be included in the templates or the layout file at this location, so at the bottom of the page. I've specified that required is false, meaning that it's optional for pages to define this section. If I would set requirement to true, all pages that do not have this section defined will cause an exception. In the next demo, we are going add script to the list view. So in the Pie list view, I'll already add support for this new section, after I use the @Section expression, passing in scripts. This script string here is the name of the section that I defined here in the layout file. I'll now be able to add script in here, which will then be inserted in the layout file at the RenderSection location.

  59. Creating an API Controller And now that we have jQuery support, we can add all kind of fancy client-side functionality to the site. I'm not going to spend time showing you how you can animate things or how you can add client-side event handlers. Instead, I'm going to be using jQuery to implement the ability to load more pies in the overview page, using a Load More functionality, and for that we'll be using an Ajax-jQuery call. This call will then be expecting more pies to be returned in JSON, and this will require us to create an API Controller. You have so far in this core been writing quite a few controllers. One thing that they all have in common is the fact that they all return HTML through the use of one of the built-in view result types. In some cases, for example, if you want to load a list of pies dynamically for client-side script, we're not interested in the HTML code. Instead, we will be happy to just get the list of pies, so the data. This we can achieve using an API controller. In previous versions of ASP.NET that we see, creating an API was only possible using a separate framework, namely the Web API framework. It was possible to have a single web application that could both show web pages and return data. Now with the introduction of ASP.NET core and core MVC, this is now more tightly integrated in a single framework. Typically, when we just want to return the data and not the HTML, we'll be working REST-based, and REST stands for Representational State Transfer. Where we use REST, we're typically going to use the HTTP standards. This means that we'll be using the HTTP verbs, such as GET, POST, PUT and DELETE to indicate the action that we'll want to perform. To indicate which data object we'll want to interact with, we'll be using the request URL. Because of the fact that REST is falling back on the pure HTTP standards, it's a very open technology. REST services can therefore be used from a very broad range of clients, including mobile apps, as well as client-side scripts in our ASP.NET core MVC pages. Let's take a look at the scheme of how we can work with a REST-based API Controller. From the client, a request is launched to /api/pies/22. Note that I am prefixing my URL here with api. This is by no means required, but I find it to be good practice so that I can differentiate between regular controllers and API controls. When the request for this URL is launched, for example, from client-side script, an HTTP verb is going to be specified as well. This can be, for example, GET, but others are possible here as well. The routing engine will make sure that our request will be handled by the correct controller, in this case, the API Controller. Typically, this controller will return a JSON response. Note that it's possible to configure the request so that it will specify the format of the data it's expecting. So once the controller has executed all it needed to do, it will return to the client a response in JSON. The client can then continue working with this response. This can be, for example, passing the JSON, and then client-side script such as jQuery, an update to your Y, to show the newly added data. As mentioned, in previous versions of ASP.NET MVC, working with the Web API was basically working with a different framework. In ASP.NET core, this has now become integrated. There's no long a different base class for API controls. So no longer will we have to set the base class for API controllers to API Controller. Here we can see some code from an API Controller. Note that the base class is indeed set to Controller. I have specified, using a route attribute that this controller should be used when a request comes in for a URL that starts with api and then the name of the Controller. So here, PieDataController. It's not possible to define the route by which the controller can be reached by configuring a route in the startup like we've done for regular controls. Like I've mentioned before, the convention is to prefix route to API methods with api, but that is just a convention. If you don't do this, your application will still work, though. Since this is just a regular controller, I can again use the dependency injection system of ASP.NET core MVC to plug in dependencies. Next, in my controller, I have again action methods. As you can see, the LoadMorePies method has been decorated with the HTTP GET attribute. This is typical for API controls. The action methods need to indicate, using an attribute, which method they accept. So for this method, that would be the GET method. Just like with regular routes, we can include arguments, such as the ID fragment for the LoadPieById method. What this means is that the LoadPieById method can be reached using a GET request to /api/PieData/id and then the value of the ID parameter will then be passed on to the method as parameter value. The whole use case for creating this API Controller is that you will be able to invoke action methods asynchronously from client-side script. When we, for example, have a large selection of pies that we want to display, you may want to return initially only the first batch of 20 pies. When the user is now at the end of the page, we can display a Load More button. Instead of performing a full post back to the server causing the page to reload, we are then going to use client-side script, which will launch an AJAX request to the API controller. The action method can then load more pies from the data source and return the JSON response. When received on the client, these new pies will then be visualized at the end of the list.

  60. Demo: Creating the Load More Functionality Using Script and the API Controller In the final demo of this module, we are going to implement the scenario I just explained. First, we are going to create the API Controller. Next we'll add client-side code to invoke the API Controller using a Load More button. The received JSON will be used to append the extra pies we've loaded to the overview list. Let's take a look. This course, by no means, was to give you a full overview of everything that is possible with the ASP.NET core Web API, a dedicated course is available here on Pluralsight via the link you see here on the slide. So I start by creating the new controller, the API Controller. Let's go to the controls folder again, and in here I'll add a new controller. I'll call this controller PieDataController, since it will be used to only return data, not HTML. I'm going to use this class for my API, and it also will inherit from Controller. This is different compared to previous versions of ASP.NET MVC and Web API where the base class was different. I'm going to add a route attribute on this PieDataController. While it's not really necessary, it's a convention that API-related routes start with API, so a static part. As you can see, I've defined the api/ and then the name of the controller as the route to access this controller and its actions. The controller code itself is pretty straightforward. I'm going to use another pie repository. I am going to use this PieDataController to load more and more pies, when the user is scrolling, so a dynamically created list. The pie data that I'll be returning needs to be as small as possible. So I'm going to add another view model that is only containing the items I need in the list. Let's add another view model in ViewModels. I'll call this the PieViewModel, and I'm only using here, as you can see, the relevant properties, so the pie ID, the name, the short description, the price, and the image thumbnail URL. Those are the properties I'll use in the list. Here in my PieDataController, I'll paste in some more code that is going to load more pies dynamically. I am returning an innumerable of pie view models. First, I'll load ten pies from the database. I'll then create a list of pie view models, and I'll culvert the pies returned from the database into PieViewModels. Now since this is an API Controller, I do need to add an attribute, and that is the HTTP GET attribute. I'll put it here on the LoadMorePies. Then that result is that when I get requests sent to this API Controller, the LoadMorePies method will be evoked, which is then returning an innumerable in PieViewModels, and it is returning that in the form of JSON. So with that, my controller is ready. Let's now make some changes to the list view, so that it will invoke this PieDataController asynchronously. I'll go ahead to the list, and I'll remove all the code that we had so far. I'm going to add an empty div, and I've named that div, pieDiv. Now I've already created this section before. The next thing I'm now going to do is I'm going to add script code here that is going to invoke my API Controller asynchronously, and it is going to ask to load more pies. The script code needs to go in a script block here. Let's take a look at the code I've just pasted in. I've created a function, LoadMorePies, which is going to do a jQuery-Ajax call. jQuery is supported because I've added it on my layout file. I am going to do a GET request to the URL /api/piedata/. This is going to do a GET request to the /api/piedatacontroller/. What I'm going to get back is JSON. If no data is returned, I'll show an alert. If data is however returned, I'm going to loop over the returned data, and I'm going to invoke this function here, which is going to dynamically create some HTML. If you look at this HTML, it is very similar to the Pie Overview Summary. In here, I used the @ model, but here, I'm not getting my data back as JSON. So I'm simply passing the properties from our JSON data. I'll then search for the pieDiv, again using jQuery, and I'll append this created PieSummaryString. Now when do I want to invoke this function? I'll want to invoke this, when the page is ready, so the first time, and I'll also want to dynamically load more data when the user is at the end of the page. For that, I'll use this script here. First, when the document is ready, I'll invoke the LoadMorePies and then, when I'm scrolling to the end of the page, I'll invoke the LoadMorePies again. Do note that this view is not typed anymore. It does not contain an @ model statement at the beginning. Everything is now done completely dynamic. Let's save everything, and run the page in the browser. Let's go to the Pies, View All Pies, for example, and we see pies being loaded, and note that the scroll bar is now, when we're close to the end of the page, getting smaller and new pies are being loaded dynamically. So you've now successfully added an API Controller, which gets invoked asynchronously using jQuery.

  61. Summary Let us briefly reflect on what we've done in this module. First, I've shown you how we can manage your client-side dependencies. As you probably remember, you can do this using Bower. Bower's now in vista view, the preferred way of managing client-side dependencies. We've then created a specific API Controller. One of the most important things to remember here is that ASP.NET core MVC and the Web API are now sharing the same base controller class. We have then created the ability to asynchronously invoke the API calls from jQuery, so from client-side script. Although this module only showed you the basics about the Web API, it should give you the needed information to extend on this scenario. Thanks for watching this module, and I hope to see you again in the next module, where we will be exploring ASP.NET Identity.

  62. Adding Security Using ASP.NET Identity Module Overview Hi there, and welcome to this module in the Building Your First ASP.NET Core Work Application on Security. I'm Gill Cleeran, and you can contact me via Twitter using @gillcleeren. Let me know if you have any questions about this course. Our application is now pretty feature rich, but it currently has one big issue. If you think back of when we were creating the order form, we didn't have to login to place an order. I don't think it's wise to put an application online like that. In this module, we are going to add some security related features to the site for guest authentication and authorization. Let's start by exploring what you will be doing in this module. When we want to authenticate users or when we want to authorize users to execute certain actions within our site, we will be working with the ASP.NET Core Identity platform. To kick off the module, I'm going to give you an overview of what ASP.NET Core Identity can do for us. Next, we will be starting to add Identity to our site. At this point in the course, it shouldn't be a surprise that we'll need to do some configuration to add Identity to our application, and once configured, we can start using it. So, we'll create a login page where users will have to login before they can place an order. And we'll finally be adding authorization as well, so that we can deny certain actions in our users to non-logged in users. I hope this sounds interesting to you. Let's do this.

  63. Introducing ASP.NET Identity Before we start using ASP.NET Core Identity, I think it's a good idea to explore what it really is, and what we can do with it. Let's start with that then. ASP.NET Core Identity is a membership system which allows us to manage users. Also, the API allows us to create login functionality, so using the ASP.NET Core Identity platform, we can add the missing functionality to our application. That's exactly what we were looking for, isn't it? The ASP.NET Core Identity API can be used to authenticate users, as well as do the authorization part. Basically, using the Identity API, we can allow the users to login via a login page. This is the authentication part. We are going to check with the system if the user is known. Once the user has successfully logged in, the user will get certain permissions in the system, different than those on the default, let's say, non-logged in user. This permission part is the authorization part and it will be used, for example, to allow the user to navigate to a certain controller. In fact, I should perhaps say, to allow or deny the navigation to a certain controller. Identity also supports working with rows, so the user can also be part of a row. The permission will then be applied on a row. If you have been working with earlier versions of ASP.NET, you are probably familiar with the Membership API. This API has been in ASP.NET for a long time, and it is generally considered good practice to use the system to handle the security in your application. The good news is that the ASP.NET Core Identity system is actually based on the Membership API. Using this Identity API, we can allow users to login using the traditional username/password combination. However, when using this approach, it is our responsibility to make sure that access to sensitive information is well secured. If we do not want to take that risk, we can use an external provider. Identity comes with support for external providers built in, such as Facebook, Google, and Twitter. By default, ASP.NET Core Identity works with a SQL database. If you have worked with Membership, you probably remember the typical ASP.NET Membership tables which will store user accounts, passwords, and much more. These tables will by default be stored in a SQL database, but if you want, you can use another system here, as well. This could be, for example, Azure Table Storage.

  64. Configuring the Application for Identity Now that you have an idea about Identity API, it's time to start using it. This way, we'll discover several of its features. The first thing I will show you is how we can add support for Identity in the application. Setting up Identity will, as you'll see in a minute, require us to follow a number of steps, such as creating models, adding the correct packages, and configuring Identity. Let's take a look at what steps we'll need to take to get things up and running. I think the following should now already start sounding a bit boring. Just like anything in ASP.NET Core, and we see Identity is a package, and I'm convinced that when I say it's a package, you automatically know what needs to happen. Indeed, we'll need to include the required packages in our product.json file. Here in the slide, you can see that we'll need to add the Microsoft AspNetCore Identity EntityFrameworkCore package to our application, and saving the file will cause Visual Studio to download the dependency. Typically, managing the configuration of the application, so making some changes in a startup class will be the next thing to do. However, I'm going to do something else first, already setting up how Identity should work with the database to store its data. Remember that I said earlier in this module that you have support for working with SQL Server, and that in that database, Identity will store the user information, the role information, and so on. Soon, there will be database interaction. I'll need to create a context again, which will act as link between the code and the database. Now, I have two choices here. Either I create a separate database for just the Identity information, or, second option is that I add the Identity tables to my existing database. If you want to use a separate database, you will also need to create a separate context class. For our application though, I have opted to place everything in just one database. And so, now, I'll need to make some changes to my already existing context class. What you see here is the code for the AppDbContext. Previously, if you remember, this class inherited from DbContext, but I want to add support for Identity. This class will now need to inherit from IdentityDbContext. Doing so will give IdentityFrameworkCore Identity specific features. A start parameter have used IdentityUser here. IdentityUser is a class that comes built in with ASPNET Core and represents a user. If you want to store more information about a user than what IdentityUser does by default, we can create our own class. Such a class would, of course, inherit then from the built in IdentityUser. IdentityUser already has quite some properties to represent a user, such as username, ID, email, roles, phone number, and so on, so all of them properties we give access to typical user information. Any other properties we want Identity to store about user can be added on this custom user class here. I won't be doing that in the demo of this course, though, as it would take us too far. Now that you have the context setup, let's take a look at the configuration changes we need to make to include support for Identity. From the code you see here on this slide, the highlighted part is what I added. The services.AddDbContext was already there, but I've repeated it here to show the registration of the DbContext with the service collection. In the next lines, or the highlighted one, I'm using the AddIdentity method to add the default Identity service using the built in classes for both user and roles. The AddEntityFrameworkStores method belongs to the AppDbContext to store the Identity information. Do note here that if I would have opted for a separate database to store Identity information, I would be registering another context using the AddDbContext, and I would then pass this context to the AddEntityFrameworkStores method, and in the Configure method, I have added the UseIdentity method. This simple call will enable ASP.NET Identity for our application. When we follow these steps, ASP.NET Identity should be correctly configured. These are the minimal settings that we'll have to configure to make Identity work. Identity does have a lot more configuration options on board, though. It's, for example, possible to set various options regarding the password policy that will be enforced when users registered. This includes settings such as the required length for the password, whether or not an alpha-numeric character is required, and so on. We can also use options to configure how security cookies should behave, such as the expiration time. We can also configure user options, such as the fact that the email used upon registration should be unique, and the lockout settings allow us to configure, for example, how long the user should be locked out when too many failed login attempts have taken place. There are more options, but let's see how they work in tote. In the snippet you can see here, we are passing to the Configure method, a lambda expression. The parameter options here is of type IdentityOptions. This class defines, for example, the password property, which, in turn, defines the properties, such as the required length, required digit, and so on.

  65. Demo: Adding and Configuring ASP.NET Core Identity In the first demo of this module, we are going to add ASP.NET Core Identity to our site, so we'll include the packages. And once that is ready, we are going to setup Identity like you see in the slides. All right, let's configure our site to support ASP.NET Core Identity. I'll start by adding the correct packages, of course, again. By default, it is not supported in my ASP.NET Core website. I think you know the drill by now. Let's go to the project.json file and add another package here. To support ASP.NET Core Identity, I'll need to add the ASP.NET Core Identity AddEntityFrameworkCore package. Let's save this, and Visual Studio will restore the package. I now have two options to support ASP.NET Core Identity in my application. I can use a different database for all the Identity-related data, but I'm going to use the database I have already created. Both options are equally valid. To do that, I'll go to my AppDbContext, and instead of having it inherit from DbContext, I'll have it inherit from IdentityDbContext in IdentityUser. Let's add the correct using statements here. By inheriting from IdentityDbContext, I automatically get support for the Identity-related features for EntityFrameworkCore. The parameter, IdentityUser, is the built in type to represent users. I can use my own type to represent users, but the built in type already has a number of interesting properties. If you look at the definition in the Framework, you'll notice it already has most of the common properties you'll typically use, such as email, username, password hash, phone number, and so on, so for us, that will do. I, of course, also need to configure the use of Identity in my startup class. Using the AddIdentity method, I'm specifying that I want to use Identity service with the built in classes, IdentityUser, and IdentityRole. The storage will be handled using the AddDbContext database and that's what I'm specifying with the AddEntityFrameworkStores method. In the Configure method, I'll use the UseIdentity method to configure the use of Identity in my application. Let's now build the application. Identity uses its own tables. To add its tables to the database, I'll need to add a migration. We'll go to the Package Manager Console again, and we'll type, add migration, Identity. When that is finished, we'll call update database. At this point, Identity is correctly configured in our application, but we aren't actually using it. Let's go back to the slides, and then, we'll return to make use of what we've done in this demo.

  66. Adding the Login Page Now that you have Identity configured in our application, we can start using its benefits. We'll start with the creation of the login page first. You'll see that it's actually pretty simple to use the Identity API for features which aren't always as straightforward if you would have to do them yourself. If we think about the login page that we'll want to create, it's, in fact, a separate view, nothing really special there. So, we'll have to create a view using tag helpers again, where the user can enter the relevant user information. Typically, we'll not only have the login view, but we'll also have the ability to register new users, and other related items, such as the forgot password functionality. These views will then be controlled using a controller that we typically include to manage all login-related functionality. This will be my account controller. And finally, we'll have to make some changes to the model and the view models as well. If you think of the account controller that we'll want to create, it will actually be just a regular controller, so any AccountController, of course, will need to inherit from Controller. On this controller, we will have at the bare minimum, in my opinion, these methods that you see here defined. We'll have a login method which will show us the login view. We'll have another login action method here as well. This one will be accepting, in this case, a LoginViewModel instance. The latter will be a ViewModel class that we'll create as part of the model changes, and it will thus be triggered when the user is sending over his credentials to perform the actual login functionality. A Register method will be needed here, as well, as well as a logout method. We'll see the API implementation in the upcoming demo in just a minute. In the implementation of the AccountController, we'll be using some important Identity API classes. The UserManager class is used to manage all interaction with the user objects in the data store. You should be thinking of this as your front to create users, delete users, and in general, do all interaction with user objects. It will also take care of all relevant changes in the data store, so updating the SQL database is done by the UserManager class, as well. Next, the SignInManager class will be used for user authentication, and all related actions. It defines methods such as PasswordSignInAsync, which accepts a username and password. When we trigger this method, we will try authenticating the user, and it will return a sign in result. Within there, a succeeded property, indicating whether or not the authentication attempt was successful. Many other methods are available in this class, such as SignOutAsync, ChangePasswordAsync, ConvertEmailAsync, and many, many more. What you need to remember here is that these two important classes of the Identity API are offering us an abstraction of the details of working with authentication and user management. The Identity API makes this sometimes difficult task a lot easier, and since underneath it's built on top of Membership, you can rest assured that the implementation of your security-related features is done in the right way. There is one more thing I want to point out here before we go back to the demo, and that is the LoginViewModel class. This class, I have added to capture all the information related to a login attempt from a user of Bethany's Pie Shop. I have the UserName property, and a Password property. The username is made required using the required attribute. And then, I have added the display attribute here as well, passing in the value that I want to show in the UI. If I omit a letter, my UI would be showing username. Next, I have attributed the Password property, with a data type, password. Doing so is an indication so that when this input will be generated in the UI, its contents should be hidden.

  67. Demo: Adding the AccountController and the Login View We'll now go back to our demo, and we'll do what I just explained. We'll create AccountController, and the Login View. Doing so will allow the user to login to Bethany's Pie Shop. All right, let's now take a look at how we can allow our users to login to Bethany's Pie Shop. To save us some time, I've already done a couple of changes. Again, you can copy all these in your own application, if you're following along, from the snippets. To manage everything that is related to logins, I've created a new controller, the AccountController. In here, I'm making use of two very important classes in this context, the UserManager and the SignInManager. The UserManager, as the name implies, contains all APIs to manage the users in the database, and the SignInManager contains all the APIs to allow the users to sign in, log off, and so on. In my constructor, I'm again using the dependency injection system of ASP.NET Core to get in an instance of both the UserManager and the SignInManager. The login method has just one parameter, returnURL. That is going to be the URL I want to redirect the user to after a successful login. The login method, itself, returns the view, which get in, as data, a new loginViewModel. Let's take a look at this LoginViewModel now. This is a simple class that has the username, password, and returnUrl property. The required attribute will be used to indicate that when we are entering the user's data that both properties will be required before we can continue. I've changed the display property to User space name for the username property, and using the data type, Password attribute, I've indicated that the password data should be hidden while the user is entering the data. I have a second login method. As you can see, this second one is attributed with HttpPost, and it is going to receive a LoginViewModel. This one will be called when the user has entered his login data in the view that we'll see in just a second. What you see if our loginViewModel that is built up by the model binders, and it is not valid to be our return to the same view. Using the UserManager doc, FindByNameAsync, we can search in the data store to see if we already have a user account with that particular name. If that is the case, we'll use the SignInManager class and try to sign in the user using the PasswordSignInAsync. We'll pass in the user and the password. If that is successful, we'll return the user to the passed in return URL if we have one. If not, we'll return to the Index Home. If however, it couldn't find the user, will return a ModelError saying that the username/password combination wasn't found, and we'll return to the LoginView again. I also have two Register methods. One will simply return the RegisterView. The second one will be called when we do a post, but again, it's passing in a LoginViewModel. We'll check if the model is valid. We'll then use the UserManager to create a user using the username and the password, and if that is successful, we'll return to the homepage. We also have a logout action method that is signing out the user, and then, returning to index home. This one also will be called using an HttpPost. Let me show you the views very quickly. We have a LoginView, which is a form where the user can enter username and password. At the bottom, we seem to have a button that will submit our form to the Login method of the AccountController, and it's doing a post in that case. The Register code is very similar. Again, a username and password can be filled in and this will post to AccountRegister. Logout view, itself, is empty. If you look back at the AccountController, this will simply redirect me to the index home. I've also added this LoginPartial partial view. This partial view will either show a login method and a register button if we're not logged in, and a log off button if we are logged in. To do this, I'm writing some razor code in my view directly. I'm using the SignInManager build IsSignedIn, passing in the current user. To make use of the SignInManager directly in my view, I need to make it available in the view. I need to basically plug in an instance of my SignInManager into my view. Remember that the SignInManager is also managed by the dependency injection system, and using the @inject expression, I can inject, using the same dependency injection system, the SignInManager directly into my view here. If you now find that the user is logged in, we show the log off button. If the user isn't logged on, we show the Register and the Login link. I now need to use the partial view from the layout file. I'll use the HTML with PartialAsync, so an HTML helper, to include the login partial in my layout file. This will ensure that this login functionality is shown on all pages that use this layout. I think everything surrounding Identity is now in place. Let's take a look. Notice there at the top right, we have the Register and Log in button. Let's click on Register. Now, we're seeing the Account Register view. I can register here, giving in a username and a password. This is using the attributes I've defined on my LoginViewModel. I'll then Register. After registering, I can now go to the login page, and log in with the same credentials. If I had incorrect credentials, you see an error. This is because of the fact that the Sign In Manager couldn't find this username/password combination. If I add correct credentials, I'll be logged in to the site, and now, we can see the Log off button here at the top. I'm now logged in. I can now add another pie to my cart, and I can now check out, but take a look at what will happen now. Click on the Check out now button. I'll copy this link, and I'll log off. I'll paste in that same link, and I can still check out. There's basically no check in place that only logged in users can do a check out. We'll need to fix that, and we'll do that in the next demo.

  68. Adding Authorization We have now added the login page correctly, and it's possible to login to the site. However, if I browse to the Order page when I'm not logged in, I can still place an order, and no one is going to stop me. Well, let's fix that, shall we? Let's see now that the authentication part is done how we can add authorization to the site. With the authentication in place, I can start adding an authorization parser. I'll need to indicate ASP.NET Core which parts, so basically, which controllers or which action methods I'm willing to protect. I'm going to start with the most basic approach, and that is controlling access on the fact if the user is authenticated or not. I can do this using an attribute, the Authorize attribute, that I'll want to add on the Controller or methods that I'll want to open up only for logged in users. Although this approach is a bit rough, it's actually something you use quite often in your NPC applications. For example, here in the snippet, I have added the Authorize attribute on the entire AccountController. Now, only when the user is logged in can action methods of this controller be used. Now, if you let that sink in, you'll come to the conclusion that that might not be a good choice. The AccountController also has the actual methods to perform the login. If you block the entire controller from anonymous users, how will they be able to log in then? Well, another attribute comes to the rescue here, the AllowAnonymous attribute. Place this attribute on the methods of the protected controller, and this will override the authorization policy. The Login method, in this case, is now again available for non-authenticated users, and that's exactly what we needed. The Authorize attribute with no parameters might, in many cases, be a bit rough. Imagine that you would add to Bethany's Pie Shop some administration pages, where she can manage the orders or the price. If you would only be able to use the Authorize attribute, it would not be possible to only allow some users, typically the administrator to get administration pages. For this reason, we can include Roles, and use these roles also from the Authorize attribute. You can see that I've passed that the Administrator role is allowed to use the methods of this controller. Users are placed in one or more roles, and when logged in, Identity will look for the logged in user. Only if the user is part of the specified role or roles will he or she be able to call action methods in this controller.

  69. Demo: Adding Authorization We're now going to return one last time to our demo and add the authorization part. We'll be adding the correct attributes onto our controllers. After this demo, our site will be capable of blocking non-authorized users of activating specific actions in our site. Now, to fix the problem that we had in the previous demo, I'll make some changes here in both the AccountController and the OrderController. First, the AccountController needs to get an Authorize attribute. We add the correct using statement here. This will make sure that all actions within the AccountController are now only available to logged in users. Now, wait a minute. If I only allow logged in users to do stuff with the AccountController, how can users then still login? That's a very good question. I'll need to add another attribute here on the Login method, which is AllowAnonymous. This will override what was defined on the controller, and thus, allowing anonymous users to invoke this action. I'll need to do the same on the second login method. I'll also need to do the same on the Register methods. So now, we cannot invoke, for example, the log out action if we're not logged in, and that's good. Now, not only the AccountController needs to be secured this way. We'll also need to make some changes on the OrderController. The checkout functionality should only be available to logged in users, so I'll put an Authorize attribute on both checkout methods. Let's see the changes that we've now implemented, ensure that only logged in users can place an order at Bethany's Pie Shop. Let us login. Let's add another pie to our cart. Checkout now. Copy that link again. Log off. I'm going to now browse to that same link again. I will be redirected to the login page. That's exactly what I wanted. So now, we've successfully added Identity to our application.

  70. Summary In this module, we have focused heavily on the use of ASP.NET Identity. Identity comes with ASP.NET Core, and is just a preferred way of adding security features to our site. I started this module by exploring the Identity framework, and you've seen what options we get with the Identity framework. We have then looked at how we need to configure our application so that it supports Identity. We have used Identity to perform both the authentication of the user, as well as the authorization, so making sure that certain actions, such as placing an order, could only be executed by logged in users. In the setup that we have used here, we've used a default configuration using EFCore. Our site is now ready. In the next and final module, we'll look at how we can deploy the application to Azure. Thanks for watching.

  71. Deploying the Site to Azure Module Overview Hello, and welcome to the last module of the Building Your First ASP.NET Core Web Application course here on Pluralsight. Time flies when you're having fun, isn't it? It's already the last module. In this last module, we are going to make Bethany very happy. Our hard work has paid off and the site is ready, ready to be shown to the world, so she start can selling her fantastic pies to her customers all over the world. Of course, before everyone can browse Bethany's pie shop, we need to deploy the site a server for everyone to enjoy it. Because we're convinced that there will be a lot of traffic on her site, we'll need the scalability of the Cloud, so we will deploy the site to Azure, and remember .NET Core was built with the Cloud in mind, so the match between our ASP.NET Core site and Azure will be a good one. Let us start this last module like we've done with all others so far in this course, that is, by looking at the module overview. This last module is actually pretty concise, but nonetheless, it'll teach us how we can deploy the site to Azure in the correct way. I will start by explain you the support you are getting in ASP.NET Core to work with different environments. I will then explain the different options, let's say at least the most important ones that are available to us to deploy our application and make it available publicly. Finally, we'll round up the module by doing the actual deployment of the site to Azure, more specifically, I'll be deploying the site to an Azure app service. Let's get started.

  72. Configuring Multiple Environments As promised, I'm starting this module with yet another new feature of ASP.NET Core, and that is the ability to work with multiple environments and how we can interact with these environment from codes. Different environments come into play when creating a new software project. Typically, it all starts with the development environment. We are in this phase or environment when the software is being written. In this environment, we typically need access to all the input information. This could mean that when the application is running in the browser that will need as much information as possible, if something goes wrong. That means including stack trays, and so on. When we are ready with the development of the software and it is ready for being tested by the customer, in our case it would be Bethany, we'll push the code to the staging environment. While this is still a closed environment, we will be mimicking the real world situation; debug information is not to be shown anymore. In terms of physical characteristics, the staging environment should also be as close as possible to the production environment, since this way we can catch any issues that may arise from the combination of our code and the configuration with the production environment. Finally, after the customer has given us the final approval, we can move the application to production. Any issues that we may have had are already solved, and Bethany's customers can finally start ordering pies online. This flow is so typical, that it's now even built into ASP.NET Core. These three environments are known to ASP.NET Core, and we can even write code that checks in which stage or environment the code is executing. Based on this value, different settings or let's use the term configuration again, can be used. Now when we go to the properties of our project in Visual Studio and we open the Debug tab, we'll see the following window here. Take a look at the highlighted part, where it says environment variables. Environment variables can be used to indicate to the code in which environment it is running. ASP.NET Core comes with one special variable named ASP.NET Core underscore environment this one is used for this very purpose; it allows us to check what is the current environment, and then in the code, we can enable or disable certain functionality based on the value of this variable. We set the variable to just any value we want, but it comes with three values that are known, let's say by convention, and those are: development, staging, and production. We change the value here in this window. By the way, the value is not case-sensitive. When we make changes in these settings, automatically yet another adjacent file comes into play, namely, the launchSettings.json file. You can find this file in the Properties folder of your project. Now you know how we can change the value of the environment, but of course, just changing this value doesn't do anything. We can now start writing code that makes the application behave differently based on the value of this variable. For this, the iHosting environment will be important. This is a service which is part of ASP.NET Core, and it give us access to working with environments. For example, using this interface, we can find out what is the name of the environment using the EnvironmentName property. Also, several extension methods are available. There are three extension methods which are available for the three known environments, namely IsDevelopment, IsStaging, and IsProduction. If you want to use our own naming convention for the different environments, that is fine as well. However, in that case, there won't be a utility method and we'll have to use the IsEnvironment method, which accepts the name of the environment and returns true if we're running on that configuration. Working with the IhostingEnvironment is again something we'll be doing in the startup of the application, more specifically, in the configure methods. You are getting an IHostingEnvironment instance in via dependency injection. In the implementation of the configurement. that you see here, I'm using the IsDevelopment method first. If this returns true, I'm indeed in development mode, and so I want as much debug information as possible, as well as meaningful error pages. I therefore will be adding some middleware components, such as UseDeveloperExceptionPage and UseDatabaseErrorPage. These will effectively result in error pages with trace information being shown in the browser in the case something goes wrong. And this is of course something I'll want during the development. If however, the app isn't running in the development environment, it should not show these pages, and therefore, I'm on adding these components. Instead, I use another middleware component, UseExceptionHandler. This allows me to redirect the user to a custom error page, let's say a friendly error page. In the background, this page may ransom entries to the log, but I won't show an ugly error to the user. If you've used other versions of ASP.NET you'll probably remember that this used to be code that typically went into the web config file. That is not the case anymore with ASP.NET Core. I can use the environment name property in other parts of my application as well. Take a look at the screenshot here. I have another app settings file, namely appsetting.production.json. This file, as the name is already giving away, contains the production connection string. Again in a startup clause, I can then change the code so that a correct app settings file will be used, based on the environment. As you can see here in the highlighted code, the AddJsonFile now accepts a string where the hosting environment.Environmentname is used as part of the file name.

  73. Demo: Creating the Error Page and Configuring the Environments Let's go back to the demo. We'll create first a custom error page, which should appear in Bethany's pie shop if something goes wrong, such as the database not being available. Next, we'll also configure the different environments in the startup clause. So first I'm going to create the custom error page in our application. Now to do that, start with another new controller. I'll call this controller the appexception controller. This is very simple controller, I'm not going to make any changes. I do have to add the correct view. So in my views folder, I'll create another subfolder, AppException, and I'll create a very simple view in there, which will just show a friendly error message to the user. That's our exception page, we'll see the action in just a second. I'm going to show you first the available environment variables. In the Project Properties, under debug, we'll find these environment variables, and by default, there's one in there, the ASPNETCORE_ENVIRONMENT, which is currently set to development. I can change this to staging or production, these are the known values in ASP.NET Core. I can give you just any value, but development, staging, and production are known. And I can use these in my application, I'll do that next. I'll go the startup file again, and in the configure methods, I'll make a change. Instead of always using the developer exception page and status code pages, I'm going to replace this code by a small check. I'm going to use the iHosting environment variable here, and if the value is set to development, then I'll use the code that was there before. If not, so if my application is in staging or production, I'll use the custom exception handler, using the app.UseExceptionHandler passing in /AppException, that will invoke the index action on my AppException controller. The IsDevelopment method will check the value of the ASP.NET Core environment variable. Now what I'm going to do is I'm going to create an exception in my code. For example, let's go to the PieController, and in the list methods, I'll throw an exception. There we go. I'm going to run things as is, so that it's still in the development setting. And let's see what happens. Let's go to the View All Pies page, and an exception is being shown here, and the browser shows the developer exception page. So nothing has really changed at this point. Now let's go back to the Properties, and change this value into production. Make sure that you save things, and let's run the application once more. Click on View All Pies. Exception is happening, but to the user we're now showing the friendly error page. So now we're effectively using our custom exception handler only in the production environment.

  74. Deployment Options To deploy ASP.NET Core applications, we now have a lot more options compared to the previous versions of ASP.NET MVC. Let us explore these different options. The first and probably the most interesting option is the deploying the site to Azure, the Microsoft Cloud platform. While we look at Azure, in fact, we have multiple options to deploy our site. The first option that we can use is deploying the site to an Azure app service. App Services is a collection of types of services of which Web Apps is the one that we are interested in for our site. A web app is a scalable solution to host Bethany's Pie Shop, and it's entirely managed by Microsoft, so we don't have to worry about installing updates on the machines, or even installing any server side software. We just deploy the application, and we're up and running. As mentioned, this option allows us to scale. We have several tiers of which we can choose. The higher the tier we select, the better the underlying hardware will be, and thus, the better performance we'll get under heavier loads on the site. As mentioned, we will deploy our site to an Azure web service in the next demo. Azure offers other options on which we can host our site as well. We could create a cloud service, or even a virtual machine in Azure, and host the site on there. In the case of a virtual machine, it would actually be required that we install and configure and IIS instance. Running an ASP.NET Core site on IIS just works. It works in Azure, and can also be done in your own premise environment. So if you are hosting a sight on your own hardware, where IIS is currently perhaps hosting already, a regular ASP.NET MVC site, you can simply keep using that same IIS to host your ASP.NET Core applications. Another completely new option for hosting is using Docker. Docker is a lightweight container engine which you can use to host applications and services. Docker is similar in some ways to a virtual machine. I won't go into details of Docker here; just remember that ASP.NET Core works great in combination with it. Finally, ASP.NET Core apps can also be hosted in the Linux environment. This is of course the direct result of the fact that ASP.NET Core is cross-platform. This effectively means that if you have a Linux server up and running, you can now run Bethany's Pie Shop from this server as well. Isn't technology a great thing?

  75. Deploying the Site to Azure Like I said in the previous slide, we are going to be hosting Bethany's Pie Shop on Azure. In the last part of this course, we'll set this up. We'll take a look at the deployment of the site in the next and also final demo of this course. However, I want to give you the first steps that you'll need to follow. First and foremost, you'll need to create an Azure account, if don't have one already. You can get started for free, the registering can be done using portal.azure.com We will be deploying the site to an Azure App Service. More specifically, we'll be hosting everything in a web app. We'll also be needing a SQL Server database in Azure, since that's where we have stored all the data for our site. The actual deployment will be done from Visual Studio, using the publish option in the Solution Explorer.

  76. Demo: Deploying the Site to Azure The time has come that we are deploying Bethany's Pie Shop. In this final demo, we will perform all the steps outlined in the previous slide to deploy the site to Azure using Visual Studios. I am now in my Azure account, so in the portal, and the first thing I'm going to do is I'm going to create a new SQL Database. So I'll go to New, search for SQL, and SQL Database is the thing I need. I click on SQL Database, and then click on Create. Let's give my database a name, I've called my database Bethany's Pie Shop Demo. I can then select my subscription, use a new resource group, or use an existing one. I'll use one that I've already created. A resource group is simply allowing me to group certain resources for easy management. I'll want to get started using a blank database. I can then select an existing SQL server, or create a new one. Let's create a new one, here. I'm giving it the same name as the SQL database, of course you can select just any name you want. And a username and password, and for me the location is Western Europe. You can of course select a region that is closer to your own location. Make sure that check box allow Azure services to access server is already checked, this will make sure that the database is reachable for my application. I'll then click Select. So our database server has been set. I can select a pricing tier here. After a couple of seconds, the prices are loaded. I'm going to select the basic tier, since that is more than enough at this point. I'll then click on Create, and sit back and relax while Azure is creating my database server, as well as my database. Over here, we can see that the deployment has started, and there we go, the deployment was successful. Let's go to the database. When looking at the SQL database, go to the Set Server Firewall. And in this case, I'm going to add my own IP, to be able to access my SQL server. I'll click on Save, and then the firewalls rules will be updated. I'll do this because I'll want to allow my own machine to create the database in Azure. And the next thing I'll do is, I'll go to Visual Studio and manage my database from there. In Visual Studio I'll go to the Server Explorer. Now, to follow along with what I'm doing here, make sure that you have the Azure SDK installed. To download the SDK, go to Azure.Microsoft.com/enus/downloads and there you'll find the correct SDK for your environment, in that case that would be Visual Studio 2015. Under Azure SQL Databases, you'll find the database that we have created earlier. I can right-click on my database, and select the Open in SQL Server Object Explorer option. This will open directly in Visual Studio, an Object Explorer to see all the tables, the views, and so in, in my database. It might be so that you get a window to enter the credentials for your database. So it seems that the database is up and running, as I'll continue to work to make sure that our application gets deployed correctly. Do not forget to remove that throw new Exception if you're following along, because otherwise we won't see all the pies showing in the live database. The next thing I'll do, is I'll copy the connection string from the Azure Portal. Click here on Show Connection Strings. And there you have your connection string, of course without user name and password. Copy this one to the clipboard. What I'll now do is I'll create a new App Settings file containing my production connection string. So I'll go to my project, Add New Item, and I'll select here, ASP NET Configuration File. The file I'll create is the app settings.production.json. In here, I'll replace the connection string with the one I've copied from the Azure portal. Don't forget to replace your username and your password with the actual username and password of your database. I'll do that next. Now I've created this App Settings production of json file, but by default, it will not be picked up. I'll need to make a change in my startup again. By default, we asked it to read out the appsettings.json file. I'll remove this line, and I'll replace it with the concatenation of app settings and then the hosting environment.environmentname.json. With the settings set to Production, this will result in the appsettings.production.json being used as the App Settings file. At this point, we'll do another build. The next thing I'll do, is I'll now call the updated database command in the package manager console to update, using the migrations that I've already created, the production database in Azure. I'll use the following command, here. So Update Database, I'll specify the context to be up db context, and then the environment parameter is set to production. Hit enter, and then the production database in Azure will be updated with the migrations I've already created earlier. And we see Done, that means success. All right, our database is now successfully deployed. We can actually explore that here in the SQL Server Object Explorer. Open Tables, and there we go, we have our orders, pies, shopping cart items and so on, so all our tables have successfully been deployed to the Azure database. And there's one more thing to do, and that's one small change in the project json file. In the Publish Options, we need to include the root folder, the views, the config, and the json files. Save this, and the only thing that's left is now to deploy the actual website. Now for that, I will use an Azure Web App. I can't create the web app directly here in the Azure Portal, but I can also use the Publish option from Visual Studio. In my opinion, using the Publish Wizard from Visual Studio is much simpler for our case. So let's do that. I will right-click here on the project, and then select Publish. I'll select Azure App Service. Select the New option here. Enter BethanysPieShopDemo as my web application name. I can add it to an existing resource group. Click on Create, the Azure App Service has been created at this point, but my application hasn't been published yet. So, at this point, the Publish Wizard is now showing me a summary of what it will use as settings. I'll click on Next here, I'll build my application for release, I do not have to include another database name. I click on Next, and then Publish. And after the Publish Wizard has done its work, it will open the website running live in Azure. Congratulations, you have successfully created your first ASP.NET Core website, which is now running in Azure.

  77. Summary and Course Closing To finish this module, let's summarize what we have learned. We started the module by looking at how we can set the value of the environment from variable, and you have used this value to check from code where the application was executing, so in which environment. Based on this value, we could then in production show the friendly error page that we have added. In the second and probably most important part of this module, I've taken you through the steps to deploy Bethany's Pie Shop to Azure, more specifically, to an Azure app service. And that concludes our time together. I hope that you have had a great time learning with this course. All that's left for me is to congratulate you on finishing this course. I encourage you to keep exploring ASP.NET Core MVC and building great applications with the future of .net. Thanks for watching this course, and bye for now.