ASP.NET Core Web App Tutorial – Part 1

Articles, Blog

ASP.NET Core Web App Tutorial – Part 1

ASP.NET Core Web App Tutorial – Part 1

Hey guys, Wes here. So, I don’t know about you guys, but I think the first place. I ever used the internet was at the library so I just finished designing a library management system in ASP.NET Core MVC and I thought it would be kind of fun to Make a series of videos documenting that project so you guys could follow along and we could do some full stack development We’re going to do everything from setting up and designing the database to implementing the MVC pattern and then finally playing around with some front-end stuff like DataTables (.js) and maybe some Material Design and Bootstrap So yeah, the project was kind of fun, and I thought it might be something that you guys would be interested in checking out So yeah, let’s take a look Okay, so let’s take a look at the software we’ll be building over the course of the next several videos So we have here an integrated library system for a fictional library called Lake View So an integrative library system also sometimes called a library management system is the software that a library uses to to lend its Assets and manage its assets As they’re lent out to various patrons who might sign up for a library card within that system. So – the library is going to control You know it’s books, magazines – things like that so it’s going to need to manage all of its inventory and sort of control, you know, how it lends out to its various patrons and to keep track of what patrons have what assets and what patrons have certain items on hold, for instance. It’s also going to want to track the different branches that belong to that library, so if you live, for example, in a larger city or region, then your library system might consist of multiple branches Let’s take a look first of all at our library catalog So you’ll see here that we just have a list of assets very simply in a table here And so we’re going to have like the title of whatever the past that is in this case. We’ll have a lot of books The author or director, and then a do we call number, so if the library’s going to do a decimal system This is just a way that they index their books yeah, we can see that the books all have covers And if they don’t we have no cover available icon here So if we click on one of the books we get taken to a detail page here so we have a lot more Metadata on this book that we can see so we’ve got an iSbn for instance a Call number again. This is the Dewey call number the cost of this asset What it is so if it’s a book or a video or anything? Its last location so the answers will be associated with a particular Branch Some checkout history, so in other words what patrons have checked out this item in the past and over what period of time and Then also a list of current holds so look at what that means in here in a second So let’s say I wanted to check this book out so I just click here and then we supply a library card id to which we to check out the book and now we can see that the book is no longer available, but it has been checked out by this patron and We can see now that we have a new checkout history started in the table here as well So the book hasn’t been returned yet, but it was checked out this time on this date So now let’s say that I’d like to check the book out, but I’m another patron and of course it’s not available for checkout yet, but I can place a hold will click place hold here and Let’s say we’ll put the new customers library card Id here and we’ll place a hold and So now we’ll see that this patron has a hold on the item and again other customers can continue placing Hold and so we’ll basically have a queue here of hold so that when our Customer tomas here checks the item back in it gets checked out automatically to the first person who had a hold on it a new checkout history record is created and The Q obviously drops one of the patrons so again if this is checked in by Mary Lee Is now automatically checked out and if you checked it in The book is back to being available for checkout. We can also very simply mark it mark the item is lost Not at which point. It can’t be checked out can Margaret sound again So that’s our kind of simple check-in checkout system To go back home and we click patrons now We can see how we can manage different patrons that are in our system, so we can see their overdue fees What library cards are associated with what library branch there so sid live if we click on one of the customers here? We can see their name address It’s an explanation that they might supply when they sign up for a library card as well as the current items they have checked out and any assets that they have placed a hold on we can also see if The customer has any fees on their account It will show up and read on their profile page here So we can see that this customer has fees due and then so we can base some logic on this and say Like if the customer has a certain amount of seeds on their account They might not be able to check out a book or a video just a small other feature we have here some other information We have on our patron object and finally if we take a look over at our branches page. We have another list view here Where we have some data about the branch how many patrons are associated with a number of assets that are associated with it? Whether or not it is open And if we click on it, we can see a picture It’s scheduled so the dates between which the branch is open the Total value of the Assets owned by the Branch and some more data so like the description and some sort of profile data on this particular branch and so each of the branches will have its own sort of profile page and The specific Data associated with it So yeah, this is our simple integrated library system or library management system, and it’s kind of fun to build it’s pretty straightforward application It’s not very large but it’s actually it would be a fairly decent starting point for an Actual system that managed sort of any type of inventory or any type of check-in checkout system. Where you have patrons? Various locations and various assets to control so I think it’s kind of a good general purpose project Particularly if you are interested in learning about the MVC pattern or just diving into some net okay, so I have visual Studio open here and So we’ll go ahead and create a new project. So just file new project and we’re going to create an core web application and I’m just going to call it library, and I’ll place this in a projects directory that I have here and We’ll make sure that it creates a new git repo and creates a directory for the solution So we’ll select ok and it’s going to ask us if we’d like to use a template and we’re going to use the web application template which is going to allow us to create an core application with MVC Okay, so you can see that by default here with this template we have a project structure in place already, and if you’ve developed in before this may look a little bit different to you if you’re coming to dotnet core for the first time so Something that you’ll notice here. Is that we have a wwe? And that’s going to contain all of our static files so csS images Javascript Third-Party libraries, and you can see that the template has brought in jquery and bootstrap, and yeah So we can actually use this directory to serve up our static files When it comes time to load some of those a little bit later, and then we have directories for our controllers and views and so the template has provided us with the home controller and Some views for the home controller here as well as some shared views so a layout and a narrow page here So the layout that’s the htML. This is actually going to be shared by all the other views in our system, and so you’ll see That we are implementing razr Syntax here So anytime you see a spiral and then some keyword here, we’re going to be using new razor templating engine and So that we can dynamically render htML on a page in these Cs. HtML files so you’ll notice that? Towards the middle of the page here after we define the head and the body tags and we have a navbar Inside of this dIV with the class container body content We have this render body method that’s being called after the spiral here And so this is actually where all of our views will be rendered by default in our application. So very quickly we’ll take a look at the application that the template has provided us with and we can just fire up the Browser clicking the iis Express button up here with a play button you Can also hit F5 as long as the library is set to your start up project? Okay, so the browser is going to pop up here, and I’ll just maximize it It may take a little bit longer to fire up the application if this is the first time that it’s being built and it’s worth noting that unlike in some scripting languages of you’re familiar with Developing web applications in Django using python or in a particular Javascript framework if you have a small node server running We’re actually going to need to stop and start or sort of anytime we work on Compiled codes of things like code that’s in our controllers and models, okay? So we have the application up here And you can see that it has created a simple home page for us that has a sort of carousel slider here And then we have a nav bar up top here with home about and contact link So if we click on these and notice that pages are getting rendered for us if you take a look at the url in A browser you can see that all the links that we click on here are relative to this home path so home is the controller that our application is using in this particular case and Then the action will be the second part of our path here so home slash about is going to look in the home controller for an about action and home Slash contact is going to be looking in the home controller for a contact action and Then our Index page looks like it’s rendering Probably the index section on the home controller by default when we have nothing in our route here So let’s take a look at where that’s configured, so I’m just going to close the browser and hit stop and we’ll come down here to Will close our view and controller folders, and we’ll come down here to the startup that’s es file Which contains our startup class? and this class contains a constructor and two methods the configure services method and configure method if we look inside the configure method you can see where we are actually telling the application how to do its routing so we have a default route here where the controller is going to be set to home and then we’ll have slash index slash and optional id that might get passed years you can imagine that we might have for example like a detail view where if we had say like an iMages controller and then select images and then Tale action where we were going to pass the id of a particular image? Then we could go to like a detail page for that image Let’s talk a little bit about this startup class as a whole so again if you’ve developed an application in the past you may be familiar with Seeing like a ab dot config file and a global Sx file here in your project structure everything now is going to be handled inside of our startup dot CS class and You’ll notice that in the constructor for this class We are actually going to be building all the configuration for this application using this configuration builder class and So all the configuration is going to be stored in a series of JSon files that might contain any Configurations that we set for application And so we’ll have pairs of keys and values in Json files that will represent the various configuration values that we might need to use and If we have new Json files that we’d like to add to our application. We can actually Just chain another adjacent file method here onto our configuration builder to apply those configurations So that’s pretty straightforward note also that we can add environment variables to our configuration builder which is kind of nice because we could store things like database passwords Connection strings or any other type of Configuration that might be particularly an environment that our application is deployed to Those can be set here and they can actually be set last so that they’ll overwrite anything That is set in the JSon files that live with the application itself so this is how we’ll build out the configuration for our application and we’ll go to the app settings that JSon file in a little bit when we Specify the Connection string to the database that we’ll be using Okay, so if we come down now to the configure services method you can see that. We have a comment here It says this method gets called by the runtime Use this method to add services to the container so dotnet core is leveraging the concept of dependency injection here And so you’ll see that as we create various services that are going to handle working with our data sources Okay working with a database or maybe some response from a remote api What have you will register all those services here in our configure services method? We’ll go through an example of that shortly as we create a services layer for this application And if you’re wondering about sort of what I mean when I say services, they are essentially just objects that have a particular functionality for other parts of our application and then we can actually inject those services and so Say like our controllers might require us if we have a controller for say our books We might have a book controller that will create later We’ll have a book service that we can actually Inject into our book controller so that it can retrieve data about the books we have coming from any particular Data source that we might Want to implement in our case We’ll be using a database But we’ll construct it in such a way that the controller simply asks for what it needs via this Service that will create that’ll be nice because we won’t be doing things like throwing a DB Context directly inside of our controller any part of the application that wants access to the database Will be instead injecting this service ok and then if we look down again at the configure method This is where we saw our use MVC called here on the app all this is Middleware so middleware is going to be the components which handle hTTP requests and which produce an HTTP response? So we’ll have things like use static files called here And will control what types of air pages are shown for instance depending on what type of environment? We’re running in and so the configure method in general is setting up What would be called our request pipeline ok we won’t actually have to do much or if anything in our consider? method for this application But we will be revisiting the configure services method as we go through and add services to our project ok so now We’ll take a look at our program that CSV file which contains our program class This is the actual entry point for our applications so you see that this is where our main method gets called and this is where we’re actually going to run our web host and So similar to a configuration builder we have a web host builder here Where we will be setting up the web host that we want to run when our application? Starts, so Kestrel is a lightweight server, and you can see we have I is used as well, which is a little bit more of a Full-fledged server and you can see that we’re going to use the startup class where we set up the configuration and middleware for our application and Eventually we call build and then once the web host is built we call run on it And so that’s basically how our application gets bootstrapped all right the last thing we’ll look at before we Get into writing a little bit of code is if we look at the app settings that JSon file? You’ll note that. This is part of the configuration files that we are building for application the only key that we have in here Right now is one for logging here, but very shortly We’ll add a connection string to the database that we’ll want to use I think now be a good time to start thinking about our data and so what we’ll do is go ahead and right-click on our solution, and we’re going to add a new project and we’re just going to call it library data, and we needed to actually be a class library, so just going to hold a bunch of C-Sharp files for us, so we’ll say ok and This data class library is where we’re going to implement any framework core So I’m going to right click here and select manage and you get packages We’re going to click browse here So we can browse online and we’re going to add Microsoft got entity framework core and So you want to make sure that you select the option that says at any framework core and not a previous version of any framework? So we’ll go ahead and install this this is going to be our our orm that’s going to be used to Essentially map the data from our entity models which are just plain C sharp objects to our data source which in our case is going to be a Sequel database using Microsoft sequel server and so to use Microsoft sequel server within a framework core. We need to also install Microsoft at any framework sequel server, so I’ll go ahead and install that it’s worth noting that with any framework core Microsoft now supports the use of other types of databases besides server and apparently even non-relational databases So I assume that means sort of document based databases like no sequel databases Maybe like Mongodb or something are supported although I don’t have any experience implementing those in a dotnet project yet But if anyone else does I would be interested in seeing it implemented, okay the last thing that we’ll add here is Microsoft any Framework tools And this is going to allow us to use the package manager console to do database migrations So in any framework core is exclusively a code first o rm meaning that We’re actually going to write all of our entity classes in Code first then any framework is going to look at the models that we created compare them to some database that will tell it to connect to and Make any changes to that sequel database is actually like creating tables from the class names and creating columns from the property names and basically generating a Complete sequel database just by looking at the structure and content of our C-sharp classes, okay awesome So now we have a library data class library that’s set up with entity framework and the first thing that we need to do to Work with entity framework is to create a class that’s going to inherit from any frameworks DB context and so DB context is essentially the link that exists between Your enemy classes and the database so as I said we’ll be writing all of our database models if you will our entity models in C-sharp classes and entity framework needs a way to make that mapping and so we need to create that particular DB context classes that will be responsible for interacting with that data as a C type object So let’s just go ahead and do it and we’ll take a look at what it looks like so By default for some reason when we create a new class library we get this class 1 dot Cs. File in here so we’re just going to rename this so right click and rename and I’m going to call this library context and We’ll say yes to rename references in the code, so it’s going to say public class library context here and so as I said we need to actually inherit from the dbContext Abstract base class that is provided by any framework, so if you hit control period Over dBContext You’ll see that you can implement this using that we need to include at the top floor file here, okay? And now we’re just going to create a constructor for this class So it’s a public library context and we’re going to pass it DB contact options so we can just call options and Then we’ll take these options and pass them to the base class constructor. So just do that. I think base options and It’s really as simple as that in terms of just setting this class up, but the important thing here Is that we’re going to have a series of what are called DB sets? And so it’ll look something like this. It’ll say Bb set and then we’re going to specify the entity object here so for instance if we have a patron object, and we’ll use on property accessories – Okay, so we don’t have a patron object yet but I just wanted to show you that this is how the library context will be structured and so our table is going to map to our Patron object and then the Properties on that patron object will map to the columns in that patrons table So let’s go ahead and actually create a patron object what I’ll do actually is right click on Library Data, and we’ll add a folder for all of our domain models here, so we’ll call it models and in a moment I’ll go over all the different objects I think we’ll need to consider when creating an integrated library system, but for sure we’ll need something to represent The Patrons and so we’ll just use that as our first example here So I’m going to do is add a class, and it’s just going to be called Patron and We’ll make it public so that it can be accessed by our library context and so the way this is going to work is we’re just going to make this a Plain Old C Sharp object and so on each one of our classes here We’ll want to specify an id that’s going to be mapped to the primary key on our sequel table Then say the Patron will probably have a first and last name And then maybe a simple field for an address probably like a telephone number which you could store As a string or as a number, and then in fact the patron will have some other objects that are associated with it so if you think of like foreign keys in a database Will have some objects like say a library card which were which will create a little bit later So we’ll actually be able to do things like this as well so say we have some library card object and any framework is actually going to be able to map our patron object then to a library card Object using a foreign key on say like the ID property of this library card object when it’s created So look at that in a little bit and in fact we can also called virtual on this which will allow us to lazy load That library card object so any time we pull an instance of patron We don’t necessarily want all of the data that’s on library library card to be loaded at that time But we’ll cover all of that in a little bit. I’m just going to comment this line out for now So you want to make sure again that? You have installed your microsoft and any framework or tools and sequel server nuget packages before moving on to this section so if those aren’t installed in this next part isn’t going to work what we’ll do is head over to our app settings a jSon file and We’re going to add a new Key here called Connection strings So it’s going to be a new object here, and we can give it a name, so I’m just going to call this one Highbury connection, and then the string should look something like this, so we’ll have say server equal to local Db xs backslash Microsoft sequel Local DB and so first of all this local DB will exist if you have Microsoft local BB installed and Once it’s installed. You should be able to confirm it at the command line And I’ll show you how here’s I’m just going to open up command line, and if you just type in equal local DB so You should see a series of databases that will be running on your computer If you don’t see em f’s equal local DB running here You should be able to type Sequel local DB start and then LS sequel local DB and that will start an instance of Ms. Sequel local DB on your computer it first amazed me to stop and delete the instance you would call sequel local DB stop and the sequel local DB and Delete but of course you want to be very careful if you are running either of those commands so back to our connection string here we now just need to specify a Database name so this can be whatever you like But whatever you type in here is what any framework will create when when we do our first migration here? So let’s just call it like library deb for instance Then it’s going to include two more parts in our connection string here the first is claude trusted connection True that just going to allow us to use our windows authentication to connect that database and the second part is multiple active result set equal to true Okay, so we’ll just save that And before I forget let’s go back to our library contacts, and we want to make sure that we Include the models that we created here, so I’m going to control period Here And then make sure that we’re using this library data models namespace so that we have access to this patron object I’m actually going to control period Up here and remove unnecessary things as well save this file Okay, and now to get any framework talking to our database we need to actually add this library context to our services collection, so In order to add a DB context we need to add entity framework to our library project, so I’m going to go ahead and right click on library manage nuget packages, and we need to find any framework or So I’m going to like this and we’ll install it here This is going to give us access to that ad dbContext method and now that entity framework core is installed we’ll also need to install entity framework or sequel server And I’ll accept so we have these New get packages installed in both of all in both our data layer as well as the web layer So let’s take a look at our dependencies and then under new Gap Okay, so I can see that it has been installed here I’m going to go ahead now and We’ll go into our Startup class and if we come down to the configure services method as I said, we’ll be revisiting This method as we want to include services for application to use we need to Call add DB context on our service collection now, so add. VB Context and we’re going to use the library Library context that we created earlier as the type so to do that I actually need to reference the library Data project in the web project I have here so we’re going to right click here, and I’m going to go to add reference and We’ll add a reference to our library data project from our solution. So say ok this will allow me to control period On library context here and Pull in the using library Data statement at the top of our file and here I’m just going to pass a lambda function that will call options options dot Use sequel server And doesn’t click we’re getting intelligence on this So let’s go to the top of the file here and manually type in new things Microsoft at any Framework or and Ok so that gives us access to the use sequel server method here, and I’m going to put the land on one line down So we can read it all and then we need to pass the use sequel server our Connection string and we can get that again through this configuration Object that we had built and we’ll call get connection string there and We just need to specify the name of the connection string that we just added to our app settings that Json which if you recall was just library connection So we’re going to go ahead and throw that here, and we’re missing a single parens okay, so you can see I feel like that structures really nicely just having this configuration object that gets built here and Then being able to call a single method get to get connection string Passing that the key from our JSon object And this is going to provide entity framework with the context that we are creating for our library application So now let’s run our first database migration and create our first database so database migration is essentially just a way of moving a database schema from one state to another and so anytime we make Changes to our schema which would be say like adding a table or dropping a table or altering some columns and so Migrations make that possible, so let’s take a look at what happens when we create our first migration So if you head down to the package manager console here and set your default project to library data first Command, we’ll run is Add – migration and we’ll say initial migration and we just need to put that in quotes, so I’ll hit return and the output we get is simply a remark that if we’d like to undo this action use remove migration But more importantly we see a new folder that was created in our library Data project called migrations And it contains this initial migration That Cs. File, so this is just a C-Sharp file That is going to go to migration for us for our sequel database, so you can see in this case It’s actually going to create our patrons table for us and create columns Corresponding to all the properties that are on our patrons domain object, okay? So if we want to commit this to the database if you will we just need to say update – database and The first time that you run this since we don’t have a database created. It’s going to take just extra seconds but what any framework is doing that is it’s going out you are using our connection train going out to an instance of Local DB and saying I don’t have a database called library’ Dev here I’m going to go ahead and create one, and then I’m going to create those table patrons because it doesn’t exist either Okay, and so you see that when it’s complete you just get done here on the console now If we go to the sequel server object explorer in visual studio. You don’t see this you can click view sequel server object explorer here, and if we look under Local Db /Ms sequel local DB and then under databases in my case I have two databases here once the demo that we looked at earlier but in our library underscore Dev database and then in the tables folder you can see that we have a Patrons table And the patrons table contains columns for all the properties that were on our domain object And so it looks like this migration was successful. So if you’ve gotten this far already, I would say Congratulations, because you now basically have a database using code first hooked up to your Application and so we can now begin to think about how we’re going to Construct the Data that will represent the various objects that we’ll need to use in our Integrated library system one thing I would highly suggest doing is if you don’t have Microsoft sequel server management studio installed I would go ahead and install that and if you open it up, it’ll look like this It will ask you when you first open it to connect to a particular server name. We’ll be able to use windows authentication You’ll just need to type in parens local DB. And then backslash and that sequel locally be and then you’ll be able to click connect and if you don’t see your database in the list of databases here just click this refresh button and Then re Expand the databases folder, and you should see it here now, so I see library Dev Now if we right-click on this and select new query Now we can actually run raw sequel against the bass that we created So for instance although we don’t have any did it and now I can select star from Patrons If I run this I can see an empty table here and again now You can see the columns that map to our C. Sharp object that we created earlier okay, so fantastic so far now I’d like to take a short step back and let’s just think for a minute about The objects that will need to be represented in an integrative library system so if we think about a library It’s basically a place where people go to checkout media yet books or video or magazines and as a library what I might want to do is manage the Patrons that come to my library to check out those assets and the assets themselves So I can see you know where they’re going if you help frequently they’re getting checked out whether or not they’ve been lost Whether or not they are being returned late, and I need to charge a particular Patron some fees And then I also might want to get some understanding of the various branches that are in my system So what library buildings contain what assets what Patrons are? associated with what library branches and so you can see we kind of have a system of objects that all kind of interact together here and on top of that we need to also develop some type of Checking in and checking out system So that we can actually manage the flow of our assets And so I think it’s fairly safe to assume that we should create objects that represent our library assets Our patrons and our branches let’s think first about what a library asset Object would look like well We would know that it would have some data associated with it like a title and author the year It was published its cost and any number of other sort of Metadata that are essentially properties on a library asset But we also need to think about how that asset relates to things like our branch locations in other words Where’s that asset typically stored when it’s checked in? And then we also need to think about its state in terms of like if it’s currently checked out by a patron if it’s lost At time did all these things occur so on one hand we have some sort of Metadata That’s directly associated with this object and on the other we have some data that will represent this objects Relationship or state with other objects in our system, okay? And so let’s think about the patron now well similar to the library app that the Patron will have some Metadata if you will sort of like person’s name and their address or telephone number Anything that sort of describes this patron and then on the other hand we have data associated with This Patrons relationship to other objects in our database So we can imagine this patron having a library card which has an ID And maybe a home library branch that this patron belongs to if you will and then finally our third Big object in the system will be a library branch and similarly the properties that might describe that library branch include its name telephone number And address and some the data that it relates to might be the total cost of assets that it controls or stores the total number Of its patrons and finally we should think about a checkout system So we need to associate an asset with a library card so we’re going to associate assets with library cards as opposed to patrons so that we have one layer of removal if you will from our patrons with the items that they’re checking out that’s going to be represented with this library card object and Then we’ll want to define a time that an asset was checked out at a time that the essay was due for instance and so Now let’s think about this library card object so a library card will have a one-To-one relationship with a patron And in the sense it will represent a sort of layer of abstraction Between the ss That a patron checked out and the patron him or herself the library card will also be used as the object that contains information about overdue fees and Assets that are checked out to the particular patron who has the relationship with the card, okay? And then finally we’ll have some additional Functionality to incorporate this idea of holds, and we’ll talk about that in more detail as we develop that feature But that’s going to allow patrons to put holds on items while they’re checked out by other Patrons Such that when the patron who has the item checked out? Turns it. It will automatically get checked out to the patron with the earliest hold And then we’ll have a concept of checkout history, so we’ll keep an audit of every checkout that occurs in the system and we’ll have a concept of assets status and so that will be a table of static data that just Contains all the different statuses that the library SI could have so like checked out checked in lost ETC alright awesome So now that we have a kind of big picture view of what our? Objects will be let’s go ahead and create some domain models for them And then we can run a new database migration so that we have a database schema created for us So I’m going to go back to the code and then I close the sequel server object explorer for now and I’m also going to minimize our migrations folder and just rearrange our Layout a little bit here to make it easier to see and what I’d like to do is in our models directory I’m just going to create classes for all the different objects that we just talked about so I’m going to click add new class and For Brevity I’m going to create a class for each of the objects here And then we’ll look at the properties on each of them in a moment and after all the classes will are created We’ll look at them individually Okay, so I’ve gone ahead and created all of our entity models here in separate classes that we’ll need to use for our application notice That I can have supply this required attribute on any of the attributes that I want to specify as non-null in our sequel database So notice that I have a class book Which is inheriting from an abstract base class library asset? Which has a model in our models folder and the reason I’m doing this is because you can Imagine our library will control a number of different types of things which still have many of the same properties that are relevant to us so anything that a library will provide as an asset will have a title a year the Status which we’ll take a look at in a minute the cost an image that we can use for presentation in our views May be a number of copies And it will be associated with a library branch so notice that I have this public virtual library Branch property on our library asset class and so this is going to create a sort of foreign key relationship between Anything that is a library asset and a particular library Branch And so when we look at the sequel table after we do our migration. We’ll see a library Branch Id on the library asset table now You may be wondering also how this inheritance is going to work? So we can actually set it up to work a number of different ways by default I think entity framework core is going to implement what’s called a table Hierarchy strategy which just means that it’s going to create a single table called library asset and so any concrete class that inherits from Library asset will be represented using a column called discriminator on the library asset table now Now to be quite honest with you, that’s not necessarily my favorite way to represent data I don’t think it’s necessarily bad, but in any framework We can’t actually directly select on that discriminator column It can make it a little bit tricky to think about how to use these concrete classes that inherit from the abstract type but it is nice on the other hand that all the Assets the library controls will be contained in a single table and not spread out across any number of any arbitrary number of other tables like book and video or Periodical or whatever other types that you might include in your system, so we’re going to work with it And it’s going to work out. Just fine next I’ve got a branch hours class and this is actually going to be used to Store the hours that are various branches are opened, and so on like say a branch details page. We’ll be able to ControL what is shown per Branch? By something we store in the database Which is a lot nicer than updating like some static HtML And so of course we are going to need an iD column and then we’re going to need the library branch that each Set of hours are associated with and then we’ll have a column for day of week and an opening close time and so each Branch Will have up to seven rows representing each day of the week and then an open and close time for each of those days next we look at the checkout table and Each of our checkout objects as mentioned when we were thinking about the sort of model structure of our application We’ll have a library asset, so in other words they like a book and a library card which again has a one-to-one relationship with the Patron and then we’ll have a day time object represent the boe fee sense and Until dates which will let us know when an item was checked out And when it was due then we’ll have a simple checkout history table Which will be a sort of audit table that again just shows when an item was checked out And when it was checked in We can make the day time Column explicit explicitly knowable here with a question mark then we’ll have a hold table and the hold is going to represent the library asset for which a hold has been requested a library card which will represent the library card that has requested the hold and Then a date that the hold was placed and this will allow us to set up a sort of cue structure Such that for any library asset. We have a series of library cards that we know requested the whole at a certain date and then so if we order that by the day time we have this cue where we can see who came first and Thus who we owe the library asset to when it’s checked in ok and then? Finally down to the library asset class Which is sort of one of the core classes of our application? And you’ll see that I have defined it as an abstract class which means that we will need it to be inherited by these concrete Child classes like book and end video which we’ll see in a minute here, but again It’s going to contain all the properties that any asset controllable by the library would have And then we have a library branch and you’ll notice I have some other attributes here on these properties In this case I can define a maximum string length and some error message I’m going to take the error message out But I put here just to show you how you can pass an error message to this string length, attribute okay, so we’ve got an address telephone number description and open date in other words say when the branch was founded and then I have a collection of Patrons and a collection of assets that belong to that library and then we can store an image url Which will contain an image that we can put on the branch detail page and we’ve got the library card asset which again is another simple class which contains the overdue fees a Created date and a collection of checkouts that are associated with that card you have the patron class which has all the patrons Metadata and what I’ll do now is uncomment our virtual library card property and create a library Branch property on it – we’ll call that home library Branch and If you want to put attributes to specify like a max length on any of these other Properties you may want to implement that as well, then we’ve got our status table which again is just some static data that will represent the name in the description of the various states that our assets can have and Then finally I’ve got this small video class. Which is just under another type of asset So in our library asset discriminator Column. We’ll have books and videos If you’re creating this app for yourself you might also consider adding Concrete classes for say like Magazines or newspapers or again any other type of asset that your library branch might to offer? Okay, now that we’ve added all of our models Let’s go back into our context and we need to add DV sets for each of these tables and Now let’s go ahead and run our next migration. So we’ll say add – migration, and we’ll call it add initial entity models and You can see that our migration gets created this time It’s going to be quite large compared to the initial migration that we ran and we’ll just go ahead and type in update – database Okay, and it says done So it means that we have actually successfully created a database schema to represent all the data that we’ll need to control in our system, and that’s a really huge first step towards developing our application, so Congratulations again if you have made it this far And now what we’ll cover in the next video is how we’ll write some services that will get used by our Controllers in our web application to query and add an update and work with all the data that we’ll store in our database we’ll also provide some scripts to populate the database with a bunch of sample data so that it’s a little bit more interesting to work with as we develop and From there, we’ll actually implement our view models and implement the Model view controller design Pattern in our web app, so this video was all about Data and Architecture and kind of thinking about how we’re going to structure our application How we’re going to structure the data that doesn’t always make for the most exciting code but it is probably the most important step and starting a new project is just stepping back and Taking it a little bit slow at first and kind of thinking about okay How is this all going to fit together? And how is it going to work? And it makes all the difference on slightly larger projects to take the time and do that upfront Makes your life a whole lot easier each step of the way thereafter, so thanks for watching this video I hope you enjoyed it stay tuned for the next video when we dive deep into creating services and laying out our Model-View-controller design Pattern if you liked this video. I’d really appreciate it if you liked and subscribe, and I’ll see you next time

100 thoughts on ASP.NET Core Web App Tutorial – Part 1

  1. @wes
    Hey Wes, I followed your these tutorial and they were great. I want to know something. In the services project can I use APIs to get the data instead of using the entity framework and creating the database. I mean can I make those services to call APIs to get data. Is that a good architecture to follow ?

  2. Hey Wes, this tutorial series is awesome. The layered approach was a new concept to me and has helped clean my projects up tremendously. I'm trying to convert this for use in a .Net standard project, using Unity for the services dependency injection into my controllers. However, I'm having some issues doing the db migrations. The console creates the migrations well, but it doesn't seem to know where the db is to update it. My data project has no connection strings in it as that is passed in the MVC project. I think this is the issue, but do you have any thoughts?

  3. Hi,
    First of all thank you very much for a great video!
    I am trying to follow your tutorial using Visual Studio Community edition on a Mac. Everything seemed to be working well until I reached the step where I need to use the Package Manager Console. Apparently the Mac version doesn't have that so I can't figure out how to do the DB migration. Can you please advise an alternative?

  4. I usually like learning from different sources and watching a 4 video series that is relatively long didn't sound like my thing at first. After watching a couple of videos, reading some articles and documentation I have to say this tutorial is extremely good, perhaps it seems boring at first but it's totally worth the time. Thank you!

  5. For NuGet package installation… please make sure to write exactly the same as it is very sensitive when searching!

  6. What if you make a change to a field name, add, delete a field or change data types. You have to do that in both places manually?

  7. I've got to say, it's been almost a year and a half since I watched this video. This really helped me learn a lot and kick-start my career, I now lead development on these projects at work. I feel like I can create anything. Thanks Wes.

  8. Sir can you prepare a video in a web application I want visual studio code editor where in user can write code and test it. Just like online coding exams

  9. Hi, I am trying to create application as per your instruction ,but when trying to Add-Migration Initial it should be thrown error " Value cannot be null."
    "Parameter name: connectionString "
    please give me solution

  10. when doing add-migration "Initial Migration" I am getting Build Failed. Any idea why this could be happening and how to fix it?

  11. Hi Wes.
    At 48:29 you define all DbSets, (except the Patron) in the LibraryContext.
    It looks like a shortcut. If so, how to do it ?

  12. For those who may face the issue:
    "Your target project 'Library' doesn't match your migrations assembly 'LibraryData'. Either change your target project or change your migrations assembly."

    Kindly set your default project into "LibraryData" instead of "Library" in the package manager console.
    PS: Careless mistake but spend me an hour…

  13. i cant find the ASP.NET Core Web Application (.NET Core)
    i only have ASP.NET Core Web Application and ASP.NET Web Application(.NET Framework)
    i wont get the same files when i do these two and i cant find a way to get the other

  14. hi professor wes. thanks for such a great work. i am going to strat this project., but i have simple query that is it possible that i work on visual studio 2015.

  15. Please I am stuck.
    Public Status Status { get; set; }
    Problem: the second "Status" word is underlined in red and the error says: Inconsistent accessibility: property type 'Status' is less accessible bla bla…

    Same goes with the public virtual LibraryBranch. "Location" is also underlined. Please reply

  16. I dont know if anybody noticed but between 28:56 and 28:57 in Library project the new file named LibraryDbContext.cs magically apeared. Somaybe this is reason why migration works in video and do not work when you try it on your machine!?

  17. Can someone please explain me what does: public virtual LibraryCard LibraryCard { get; set; } do ?
    Like, how does this line of code make link between Hold and LibraryCard… ?

  18. while Installing the EntityframeworkCore for the Library i am getting the error as
    Description Project File Line Suppression State

    Error Package restore failed. Rolling back package changes for 'Project'.

  19. Hi Wes
    I am facing issue with migration command can you please help me with this ?
    The EF Core tools version '2.1.1-rtm-30846' is older than that of the runtime '2.1.8-servicing-32085'. Update the tools for the latest features and bug fixes.

    System.ArgumentNullException: Value cannot be null.
    Parameter name: connectionString
    at Microsoft.EntityFrameworkCore.Utilities.Check.NotEmpty(String value, String parameterName)
    at Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(DbContextOptionsBuilder optionsBuilder, String connectionString, Action`1 sqlServerOptionsAction)
    at WebApplication1.Startup.<ConfigureServices>b__4_1(DbContextOptionsBuilder options) in C:UsersNandiniisourcereposWebApplication1WebApplication1Startup.cs:line 42
    at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass1_0`2.<AddDbContext>b__0(IServiceProvider p, DbContextOptionsBuilder b)
    at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.DbContextOptionsFactory[TContext](IServiceProvider applicationServiceProvider, Action`2 optionsAction)
    at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass10_0`1.<AddCoreServices>b__0(IServiceProvider p)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
    at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__10`1.<AddCoreServices>b__10_1(IServiceProvider p)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetServices[T](IServiceProvider provider)
    at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextTypes()
    at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextType(String name)
    at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
    at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0()
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
    Value cannot be null.

    Parameter name: connectionString

  20. I noticed that when I did an update-database that some of my tables used the plural form of the class name and some did not. For example it created the Checkouts table from the Checkout class but created a LibraryBranch table from the LibraryBranch class. So when I went to run the SQL script you created for filling the various tables, I received an error showing that the table names did not exist. I deleted the database twice, including the migrations and tried again and got the same results. Is there something I am missing?

  21. Hey Wes — Here's a comment you really should answer:

    *“Ivan Marijanović
    – 3 months ago

    I dont know if anybody noticed but between 28:56 and 28:57 in Library project the new file named LibraryDbContext.cs magically apeared. Somaybe this is reason why migration works in video and do not work when you try it on your machine!?”

    He has an extremely good point there. Only by reading this in the middle of writing my "Initial" comment I found out why your migration doesn't work for us.

    You skipped a step where that file LibraryDbContext.cs was created.

    WTF did you do when you cut the recording???

  22. Thanks to Ivan Marijanović for noticing – just after 28:55, a LibraryDbContext.cs file magically appears in the solution within the LibraryData project! Due to an apparent editing mistake, the creation of this file was cut. We need this context to run our migrations! Check out the code for the file here: if you'd like. Sorry for the confusion!

  23. In case anyone hasn't got the Command Window and the Package Manage Console open down the bottom like I didn't,
    follow the MSDN links below to do it. — You likely don't have the latter, unless you've added it before.
    Command Window:
    Package Manager Console:

  24. Hey Wes
    The biggest problem I'm having is, when I try the migration,
    I get an error at the end that says:
    "Value cannot be null.
    "Parameter name: connectionString"

    Obviously I've checked the string and values, and they are all fine, and the Key I use matches.

  25. Thank God I found this amazing tutorial series !!! Kudos to you man, keep uploading videos of ASPNET CORE MVC with practical strategies. Thank you very much!

  26. I found this to be a very good tutorial. The only difference I have so far is I reverse engineered the Database Models & Context using the Scaffold-DbContext Command from a DB project published to local db 🙂

    Great video Wes!

  27. Hi Doyle! You did an amazing work here… I really appreciate that. How about creating full stack BLOG project with .NET core and Angular or Vue for example? That would be awesome! Thank you! 🙂

  28. Hi Wes, great series! I went from knowing nothing about .NET Core to being able to develop my own small webapp. Apologies if this has been asked before, but how does your implementation fit with the Repository and UnitOfWork pattern in .Net?

  29. I noticed in your video you had LibraryDbContext.cs inside Library project. I don't know how is it that come from? Could anyone tell me, Thanks for your video, I learn a lot of things.

  30. Does anyone know the name of the font 'Library Management System' is written with in the video miniature? Thanks

  31. Hi Wes, I'm getting an error "Build failed." when I try to add-migration "Initial Migration". I have added the LibraryDbContext.cs file to the Library project but no luck.

  32. Hey, when I create a new project, I miss the bower.json file. Do you know the reason for this? I am using visual studio 2019

  33. hi i have prob when i run the IIS in the beginning of the tutorial related to home control u mention i cant open in chrome whenever i try it giving me error
    pls help me out with this

  34. Hi, thank you for taking the time to provide this tutorial. I always appreciate a project video with amazing content and something worth seeing at the end.
    I have a question based on using Visual Studio 2019, i'm seeing some errors when following this video. The Startup.cs file in the Library project is coded up differently? Sadly I don't understand enough about coding to be able to pull apart the differences and see what is happening or why they are different.

    LibraryContext.cs file in the LibraryData project is showing an error at: public DbSet<Patron> Patrons { get; set; }.
    The error states: "Inconsistent accessibility: property type 'DbSet<Patron> is less accessible than property 'LibraryData.LibraryContext.Patrons'"
    Is there any advice on this issue please?

    EDIT: I opened up the Patron.cs file and made the class public (public class Patron) and this seemed to do the trick…

    Also, at the end of the video I am trying to do the migration, and as others have seen there is a missing file. When I look at your github, the file is named differently, and i'm sure the code is similar to what is in yours at 46:15, but I am wondering why it is not working?

  35. Great tutorial! I have found differences in creating project. I am using Visual Studio 2017 community. I created project like in video. C# .NET core Web app and it was razor with no controller. I created it second time using mvc and used individual user account that created database connection string for me. Now I'm having a little trouble with two database contexts so I combined LibraryData to Library project and are using ApplicationDbContext for user and Library database. Just put DbSet<Patron> in ApplicationDbContext and you have only one database with all tables.

  36. I just started this tutorial. Right off the bat I noticed that my startup.cs has a different constructor. Mine utilizes
    public Startup(IConfiguration configuration)


    Configuration = configuration;

    But this video shows a constructor of IhostingEnvironment?

  37. Thanks Wes. Great job. 31:04 I get Value cannot be null. (Parameter 'connectionString'). Appsettings.json is correct, startup.cs is correct. If I put in just "add-migration" it asks for a "Name" parameter. I have put in both Initial Migration and "LibraryConnection". It doesn't like either. What do you suggest?

  38. great explanation, although im having a problem installing core framework giving me errors. Does anyone know how to solve these errors. Note: fixed it by installing other versions of framework

  39. This is one of the best "Production Level" demo tutorials out there thanks. All the others are like basic beginner level.

  40. Great course Wes you explain things very well and I am enjoying learning from you. Did you get round to uploading to GITHUB? If so can you please let me know how to get to it? Thanks again.

  41. This tutorial is very easy to follow and I already subscribed into this. Though I did not able to follow how DBSets were added instantly on LibraryContext (46:15 – 46:30). Please share the keyboard shortcut or how you were able to do that. Looking forward to more videos. Great Stuff!

  42. Appreciate the video. I couldn't make it thru the Part 1. VS2019 is just different enough to make it difficult to follow. Not new to development but new to VS. During the overview the class structures are different, the VS gui is different….. Dang it, off to find something this good for VS2019.

  43. Excuse me sir I'm looking for a Web site development course written in, that contains board ,login and register function in it.
    Have you uploaded any video about that?

  44. anyone else having issues following this, and using VS 2019? …Nuget packages error my build, some wont load in project. Migrations wont work, even when i unload the original project (Library)

  45. i got confused with the thumbnail. the numbering is reverse. this video says:
    "Library Management System

    Part 4"

    then the part two says:
    "Library Management System

    Part 3"

    then part three says:
    "Library Management System

    Part 2"

    then part four:
    "Library Management System

    Part 1"

    then part five:
    "Library Management System

    Part 5"

Leave a Reply

Your email address will not be published. Required fields are marked *