Introduction to .NET Microservices (.NET 8)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
foreign [Music] are you looking to learn what microservices are or are you trying to get started and gain some real world hands-on experience with.net microservices my name is propane and welcome to dotnet mastery if you have not subscribed to the channel make sure to do that right now that way you do not miss any free content that I upload in the.net domain microservices is one of the buzzword in programming if you look for a new job microservices is one of the key features that is coming up more and more often every time a system is lacking or it is getting too big someone will have a suggestion that maybe we should look into microservices but it is critical to understand what exactly it is and how to implement it correctly that is my motivation behind this course my goal is to introduce you to the microservices architecture while giving you a real world project to see how microservices communicate with each other and what are the problems that we encounter and how to solve them microservices is made up of individual API projects in simple terms but in reality there is much more to microservices than that but as microservices are composed of individual apis we will be spending quite some time in building small apis and then we will focus on the key concept of how individual API communicates with each other and how the microservices architecture comes together we will be building multiple small apis in this course including one API that will be responsible for authentication and we will do that using.net identity once we build the apis then we will see how API communicates with each other if you are excited about what microservices are and you want to learn by building a real world project in microservices this is the course you are looking for I hope you will join me in this exciting journey of microservices and let me show you what we will build in this course in the next video let me give you a quick demo of what we will build in this course we will be building multiple apis in the services here you can see we have five API and we have a web project that consumes all the API endpoints let me run the project here and I will run all the apis and the web project perfect let me open the web project here and you can see we have a e-commerce application for a restaurant I have already logged in here as the admin user but if you log out we have login and register buttons when a user registers here they can select a role so that means we have role based authentication on admin and customer and based on the role we will have different functionality let me log in here as an admin role and once we log in we will be redirected to the home page where we can add products to our shopping cart perfect we have toaster notification here let me add few products here and we will have a shopping cart where we will store shopping cart for each user in database I also have coupon codes if you apply them the order total is reduced as well the order total gets updated right here in the shopping cart it is calling the coupon API to retrieve the coupon code and apply that coupon when we hit the button on top of that we have a functionality of email card when we click there it will not send an actual email but it will trigger asynchronous microservice communication and then the log of the shopping cart will be added to a database of a different API endpoint if that sounds too complicated right now do not worry when we progress with the course you will understand the complete architecture and the reason behind email card functionality that I have added here on top of that we also have content management as an admin user where they can manage the coupon or they can create new coupon edit or delete any existing coupons with that quick demo let me get started from the next video now on the apis here we will also have a role-based authorization a customer user cannot create a product only an admin can create delete or update a product there is a lot to cover in the course let me get started with all of that from the next video before we move forward this will be an introduction to dotnet microservices if you want I have a more detailed course where we will take the complete application that we will build in this video and I have covered that in the full course as well on top of that there is about 10 hours of more content where we will build many more micro Services integrate them together and I will also show you how to implement that using rabbitmq you can find all the details on netmashtv.com and there you will find the complete course with all the topics that are covered that being said on YouTube here the course will give you a basic introduction of microservices so do not get disappointed you need to understand the basic fundamentals first before you add more features to the existing application let me try to answer the big question on why microservices are what advantage does microservice brings to the table microservices are independently Deployable what that means is if in a project there are multiple micro Services we might be working on one microservice at a time or it could be possible that each team has one micro service that they are working on and they can be deployed individually rather than deploying the complete project with all the micro services because of that we do not have dependencies on the other working pieces of the application when we are working with an individual microservice when we work with monolithic application that is typically one big application and the team works on that so when a deployment has to happen the complete application has to be deployed rather than small application or a small microservice but when we work with microservice architecture each microservice can be deployed by itself microservices are great when it comes to scaling as well in a traditional monolithic application we typically have one server and we might scale that out to multiple instance but when we have to scale up we have to scale up the complete server with the complete application but when we work with microservices we can increase the resource on the service that needs them rather than increasing it for the complete server as an example if there is a micro service that is responsible for handling the bulky exports of our website and if we want to have five instance of that that way the downloads are super quick then it would be much easier to scale that microservices and not touch any other microservice but if it was a monolithic application you might have to scale out all the instances of the main server to have multiple instance up and running you can see because of that scaling is much more efficient when it comes to microservice architecture microservices do not typically have bulky code because the complete application is broken down in multiple micro services the code base of each microservice is smaller as compared to monolithic application because we are breaking things out with microservice now that does not mean that microservices will always be small the only thing that you should remember is microservices the only factor that you should remember is one microservice would typically be responsible for one functionality lastly there can be many micro services in an application so it could be possible that one of the micro Services goes down but the other micro services will be up and running because all of them are hosted individually debugging and making sure that the microservice comes back online will be much faster as compared to a monolithic application and because of that it will reduce the downtime of our project these are some of the basic benefits that microservices brings to the table let me walk you through one of them with an example here we have a front-end application and we have poor microservice we have a microservice that will deal with loading all the products and managing that we have one for managing the shopping cart we have one to manage the order and we have one microservice that is responsible for sending out all the emails in our project now let's say for some reason email microservices fails but all the other micro services are up and running in that case when a user registers or places an order a message will be sent to some place in a message broker because the email API is not running the message will be stored there let's say after few hours when the email API is back up and running it will start processing all the messages that were supposed to be delivered and then send out the email but even if the microservice for email was down the other micro Services were up and running similarly let's say if the order microservices goes down everything else will be functional so at least a user will be able to browse the product add that to the shopping cart they will not be able to place the order or they will have to wait for some confirmation that depends on how we design the application but main thing that you should remember here is with microservices if one microservice goes down the application will still be up and running that is way different if we have a monolithic application FN monolithic application the server goes down the complete application goes down I am giving you a 10 000 feet overview right now to introduce you to some of the advantages of microservices but if some things are not making sense right now or if you have questions about that please hold on to that as we progress with the course and start building the microservices add communication between them everything will start making sense microservices is an architecture where there are multiple micro services or apis which are Loosely coupled and they are independently Deployable services they work in conjunction with each other to produce the complete final solution when we compare this architecture to monolithic application this is different because in monolithic application there is one big solution inside that everything is coupled together and it is tightly bounded in the diagram here on the blue and gray boxes you can see individual micro services each one of them is responsible for its own functionality like in an e-commerce application we will have a product microservice we will have a coupon micro service a microservice for shopping cart order sending out emails and a rewards API that will be responsible to track all the rewards a user gets by placing order we also have a.net identity microservice that will be responsible for authentication and authorization across all the other micro services because they are not tightly coupled they might use different technology like one microservice can use SQL server for database while the other one can use mongodb or nosql any other database or even different programming language like one can use C sharp one can use JavaScript one can use Java or any other programming language it is not required that microservices should follow the same technology stack because they are Loosely coupled microservices can communicate with each other with a combination of rest API calls or message Brokers like in this example you can see we have a service bus in the center with the yellow color one thing that you should remember is business requirement will divide the micro services and each service will be responsible for its own functionality let me take a look at this with a better example we will first understand how a traditional monolithic application would look like if you have a big shopping cart application you will have products shopping cart order management and all of that will be in one architecture and all of that will be in one project on top of that there will be one database and there you will have all the tables you can use anterior architecture create folders get fancy on how you organize everything but still everything will fall under one project and there will be one Central database to hold all the data now there are few advantages of this architecture a monolithic application centralizes all the data and also all the code will be in one central place if a developer has to make a change he can run the complete application and all the pieces of application will run together so it might be easier for a developer to debug an issue and fix that most of the applications are monolithic application and that works absolutely fine but once the application starts to grow and you get more and more components and data added that is when the actual problem starts in the monolithic application there are tight dependencies so later on if the project grows then getting rid of these dependencies is a nightmare that being said let's take a look at how the same application would be implemented in a microservices architecture in this case you can see all the components that we had like shopping cart product and Order component they are now individual.net core applications or API on top of that you should notice all of the three application also have their individual database and they do not share a common database there will be a separate application that will interact with the individual micro services and with this architecture maintaining all of the services are now quite easy each of the service can be implemented in a different programming language or have a different type of database depending on what the requirements are and then they can communicate with each other now of course if all the micro services are in one project you should technically keep the technology stack same unless there is an advantage because always remember that if you have more technology then you will have to spend more time and effort in maintaining them or updating their versions rather than updating the same technology stack one thing that gets easier is let's say the order component needs more computation time you can easily scale that one database if it requires more space and the other database you can keep them smaller that way you can scale one instance or one database and not toggle everything else with that you should have a brief overview of how architecture is different from monolithic as compared to a microservice architecture in the gray box here you can see we have different microservices for product coupon shopping cart order management email and Rewards each one of the microservice will have their individual database we will have a dotnet identity microservice that will be responsible to provide the JWT token for authentication and authorization across all the other services that we have we will also build an MVC application that will interact with all the individual micro services to bring everything together there will also be a Gateway MVC application will interact with Gateway and Gateway will redirect the request to the individual API when we have to work with communication within services like shopping cart here you can see communicates with the product service communicates with the coupon service and so on those communication will be synchronous communication we will see how to accomplish them and then you can see dotted lines here that are using service bus for communication those communication will be asynchronous communication and we will see how to pass message to the service bus how to extract them and process all of that I have also written port number that we will add to the different API endpoints right here so you can take a picture of this architecture keep that on the side that way you will always have a rough idea of what is the architecture of our project that we are building in this course let me walk you through on what will be all the tools that will be needed for this course first thing will be visual studio and dotnet 8. right now.net 8 is in preview so if you are using visual studio you will have to download the visual studio 2022 preview version if you want to follow along the same course in Visual Studio 2022 then you will use the.net 7 and not.net 8. for net 8 you will require the preview version next thing for the database we will use SQL Server now make sure to use SQL server and also install SQL Server management Studio you will have to install both of them to get SQL Server management Studio up and running on your local machine finally you will require an Azure subscription we will be using Azure service bus for communication between the apis that we will build that will not be a free service I believe it will cost about 10 dollars for the whole month but that should be sufficient to learn microservice architecture if you have never joined Azure I believe they give 150 to 200 dollars in free credit to try the Azure services but these are the tools that you will require for this course before you move ahead with the course let me clear some things here I want to cover what this course is not about when someone hears microservices they right away think about docker that is a misconception microservices and Docker are not related you can have a monolithic application with Docker as well Docker has its own advantages and why you should use that but when it comes to microservices and learning the fundamentals behind how apis communicate with each other what are the pitfalls there we do not want to add any other complexity rather than what is needed for microservices if I add Docker onto the course it will make the course way more complex for someone who wants to learn microservices because of that I want to make clear that Docker will not be covered in this course next thing that I want to clear is with microservice architecture one advantage that we have is when we have different API endpoints we can use different technology like in one API we can use the dotnet API in the other one we can use minimal apis we can even use a completely different programming language for other API and same applies for database we can use SQL Server we can use mongodb sky is the limit when it comes to multiple API endpoints because they are not related but if someone is getting started on learning microservices that is not the route that you should take what I will rather do is I will be using.net apis I will be using Entity framework core and I will be using SQL server in all the apis that we will build that will make sure that you do not get stuck in multiple technology stack and you understand the main concept of what is a microservice how microservice communicates with each other and how the architecture comes together once you understand that if you have to implement the same API in different programming language or different database that is not a big deal let me walk you through on what are the prerequisites that I expect for someone taking this course you should have a basic understanding of.net core what I mean by that is you should be comfortable with MVC programming language and how web applications are built with.net core on top of that we will be using Entity framework core so you should have a basic understanding of credit functionalities using Entity framework core and then finally microservices is basically small API endpoints even though I will build everything from scratch I expect you to have a basic understanding of the.net apis with Entity framework core as well but if you are not familiar with these functionalities I have free course on.net Mastery that will walk you through all the fundamentals that you require for API with Entity framework core as well as dotnet core MBC make sure to get those courses from.net Mastery before you proceed further if you want to get a refresher on the basic introduction throughout the course you will require some project resources or if you want to access the PowerPoint presentation or images that are used you can go to courses on.netmatchedweet.com and navigate to the course here we have.net core microservices if you go to the details tab here I have the link here for GitHub code that will take you to the git repo then make sure to download the course content because that will have all the content that you will require like Snippets images and so on if I open that here you can see there are two folders I have the content for old course if you are taking that but that will be removed in December of 2023 the current courses.net 8 cores and that is what you should be doing there I have all the images and in Snippets folder I will have the code Snippets with HTML that we will use during the course make sure to download project resources before you continue in the next video on top of that I also have free Content on.net Mastery that you can check here and many other courses if you are interested but with that let me continue back to microservices I will open my visual studio here and we will go to file new project now we need to select what type of project we want we know we are building a microservices architecture so it makes sense to divide everything in their individual folders but right now we do not have anything with an empty solution it was there in the templates before but for some reason it has been removed so let me create an asp.net core Mt project name is not important but the solution name here let me change that to be mango I will be deleting this temporary project I only want to create an empty solution to get started framework will be dotnet 8 that looks good we do not want to use the top level statements let me hit the create button perfect it has been created here now like I said before we do not want any project let me delete this project let me right click open that folder and I will remove the web application one we only have an empty solution with that configured let me create folder in the next video rather than creating everything in the solution here it is better if we organize that in a folder structure we will right click in the solution add a new folder and I will call this the front end folder here we will be placing our front-end application which will be the MVC web application that will call our microservices next folder that we want will be a Gateway folder when we work with microservices initially we will be invoking the microservice directly but down the road we will learn some Advanced concept with Gateway and that we will place inside the Gateway folder after that we will have something called as integration and that folder will have something that is related to messaging which I will explain later on as well right now these are only empty folders but as we add projects in this folder everything will start making sense the final folder that I want will be the most important one and that will be services inside Services we will create all of our different micro services or rather the API endpoints we will get started with creating our first API endpoint that will be a coupon API where we will be creating coupon codes that we can apply to our product so inside the services folder we will create a new project and that will be an API project we will search for API here we have the asp.net core web API project name I will call that mango dot services dot coupon API that looks good here we will be using.net 8 and we will be using controllers we do not want minimal API that looks good let me create the project with that created let me run the application here and see how that looks we need to allow access that is okay and perfect in the background here you can see it is running on localhost 7123 now when we are working with the micro Services project we can use port number that are closely assigned rather than something random if I switch back to the presentation here you can see for the coupon API we were planning to use port number 7001 we can go back to our code and we can update that let me stop the application here and that will be insert properties launch settings.json here we have 7 1 2 3 for https let me make it 7001. let me switch back and yep that is exactly what we have for coupon save that and run the application perfect that looks good we have created our coupon API that API will be responsible to perform crud operations on the coupon model we do not have that yet and for that in the coupon API we will create a new folder for models in there we will create our model which will be a class file I will call that coupon.cs when it comes to creating a coupon you can be very fancy but I am going to keep things super simple we will have a coupon ID a coupon code a discount amount will basically be how much discount they will get and if there is any minimum amount after which the coupon should be applied that will be the four properties that I want in my database right now we only have our model but now we need to think about adding that to our database but before we go into the database logistic when we are working with an API this will be the core model of our database let's say there was also some other properties like date time and we had last updated as well as create a date now those properties when the front-end application is consuming we do not need to pass that they are only for the Locking purpose so it is possible that every time when someone is accessing a coupon we do not want to pass all the field for that typically in an API we do not return the complete object we rather return something called as a dto and that will have all the properties that we want now right now to keep things simple I am going to make dto and coupon class the same but that is a common scenario that you will encounter whenever you are working with an API in the model folder here I will create a new folder for dto and in there I will add a class that will be coupon DTR like I said before the properties will be same for now so let me copy and paste them here one thing I would also like to point out is you can see based on the project I have different tab color right now I only have one project so everything is in one color but if you want to enable that feature you can click on the gear icon here and that is colorize document by I have project selected that will give you the same colorful tabs like I have but this looks good for the coupon dto how we will do conversion from coupon to coupon dto and other concept we will cover when the time is right we have added the coupon model and we also added coupon dto but we need something to convert coupon dto to coupon or vice versa when we have that requirement we can do that manual mapping but it is tedious and rather there are many packages that we should use to enhance our speed and make code more elegant one of those package is Auto mapper and that as the name suggests is responsible for mapping one object to other so we will add Auto mapper to our project and we need to store our coupon in a database I will be using SQL server for that and for that also we will have to add new get packages to configure Entity framework core to access our database in the coupon API project we can right click manage nuget packages we will go to the browse tab here and the first package that I want is Auto mapper Auto mapper let me install that one and we want to use Auto mapper using dependency injection for that we will require automapper.extensions dot Microsoft dot dependency injection perfect we added both the project for that now we need Entity framework code you can see intellisense is already displaying me those package but if not you can search for them as well right here we have this equal server let me install that package perfect that looks good next package we want is the Entity framework core package and we have Microsoft dot Entity Framework code.tools we will be using the tool package to add migration so let me install that and here if you notice I have the include pre-release selected because of that I am able to use.net 8 preview 3. if you uncheck that then the version you will see is.net 7. we want to use.net 8 for our project so make sure that you have this checked and then you install the right package version one thing that I will point out right now is if you are using preview 3 and let's say preview 4 or next version is released keep using the same version in that micro service if you have a different micro service you can use a different version there that is okay but inside the same microservice if you use different version things might not work so always keep that in mind when you are adding nougat packages along with that intellisense is also displaying authentication.jwt batter we do not have Security in our API right now but later on we will be adding API we have that package here so why not install that in our API as well if I go to the install tab here perfect you can see all the packages that have been installed with that let me continue from the next video we need to create a database using Entity framework core we have already added the new get packages for that so all we have to do is add something called as a DB context I will right click on the project here add a folder for data and in that data folder I will create a class file call that FDB context or sometimes I'd like to call that application DP context when we have to configure Entity framework core in our project this class must implement the DB context class that is inside Microsoft dot Entity framework core along with that there is one more configuration that we have to do is whatever we get in the Constructor here as DB context option we have to pass that on to the base class that is DB context what we have here is a default setting that is required for Entity framework core and with that when we have to create our coupon table in the database in the DB context here we have to create something called as a DB set for that class file so DB is set here that will be on the coupon class at the using statement and what do we want to call that table in our database I will give that a plural name and this coupons will be the table name in database then if we go to the coupon model here we can add some data annotation like coupon ID will be primary key of the table then coupon code here make that required discount amount we will also make that required with that configured we have created our application DP context file but we need to create database for that we need to do some configuration inside program.cs file we need to configure DP context inside the program.cs file that file is basically the main file of the application where you will configure all the services and the request pipeline right now we want to add something to our services here and that is application DP context we have to tell our application that hey we will be using Entity framework core for our database and we will be using SQL server and the apptp context or rather the DP context for that is inside the file appdb context we need to Define that right here so on Builder dot Services we have the add DP context method and there we have to define the class that implements DB context that is appdb context and here we have to Define some option that option will basically tell that hey we will be using SQL server for our database so option dot we have a method use SQL Server you can see that is inside Microsoft dot Entity framework core and then we have to pass the connection string now we can hard code that connection string right here but that is not a good idea what we should rather do is inside the app settings.json we can Define connection string right here now in production you can use the Azure keyword but we will not go into those complexity we will be using app settings for now right here we will Define a section or rather you can see there is a predefined section for connection strings we can directly use that we can give it a name let me call that default connection and there I will write or rather Define the connection string first we have the server name and for that we will open SQL Server there when we hit the connect icon we have a server name now whatever server name works for you you can copy that I will copy this because you can see when I try to connect I am able to connect there for many of you if you add a DOT and try to connect it might work I do not have that configured on my machine but I have the local DB msql local DB so I will copy that paste it right here after that we have to Define what will be the database name so we will add a semicolon database and then let me give it a database name of mango underscore coupon after that I will add couple of more Fields here for trusted connection to be true and trusted server certificate to be true with that our connection string is looking great but how can we access that connection string and pass it on right here if you notice in app settings we have default Connection in a section with the name of connection string because of that we have a special method that will only work for Section with the name of connection strings if you had that as connection string or anything else it will not work but because we are using the default one on Builder dot configuration we have a method get connection string and if we go there you can see it retrieves the value with specified key from connection strings section and that is exactly what we have in there we have to pass the name key name if we go back I can copy default connection paste it right here we need the closing bracket here and perfect that looks good that will retrieve the connection string and pass that to use SQL Server now that we have application DB context configured here how do we create our table and database it is simple we will be using something called as migration for that we will go to tools you get package manager and package manager console now if you don't know about migration or how Entity framework core works I have a free course on API on my YouTube channel so make sure to take that course to get more familiar before you proceed on the course because even though I would love to start from scratch I want this course to be focused more on microservices and not on API and how the Nets and grits of API work so next we need to add a migration let me say add migration add Coupon to DB add that perfect migration is added here and it is creating the coupon table when we need to create this all we have to do is run the command update database but when we do that you will see our first error message you can see keyword not supported trusted connection I want you to Google the error and find out what is the solution I hope you were able to figure that out I intentionally introduced an error while pasting it here this must be trusted underscore connection if there is any mistake in the connection string when you try to update database you will see error message like this after you fix that if you run the command update database you will still see an error message and this error message might go away when you are programming the edit that you see here can easily be resolved if you right click on the project and select edit project file invariant globalization when that is true that is when we see that error message I have already reported that to Microsoft so by the time you are taking the course this might already be fixed but once you disable that if you do update database again it will work and perfect that works if I go back to SQL server and refresh the database we have mango underscore coupon and perfect we have the coupons table we have four columns there so our table is created successfully and we were able to push our migration we have created our coupons table in the database but we need to populate some entries in there what we can do is I can see some database directly that way we do not start with an empty table seating database is very simple with Entity framework core right here we have to overwrite the on model creating and in there they have a default model builder before you see any record on the base class we have to pass the on model creating with the model builder that we receive in the parameter if you do not add this line things will work right now but later on if you add identity it will not work so it makes sense to add it and forget about that you can think about this as a basic configuration that is needed to seed some record in the model tables after that to seed something we can use the model builder dot entity on coupon we have a method hash data and there we can pass a new coupon object that will be the record that will be created in your database we can add some dummy record there with the coupon ID of one coupon code let me call that 10 off discount amount and minimum amount the next one let me make it two I will call that 20 off 20 discount and minimum amount let's say 40 dollars perfect now how do we seat our table if you open the package manager console and if you add a new migration call that seed coupon tables perfect you can see it is calling a method insert data and it is inserting two records that looks good now rather than updating database what I want to do is if there are any pending migrations I want when I run the application it should automatically apply those migration that way we do not have to write the command update database doing that is super simple let me close all the tabs here other than app TP context well not apptp context I wanted program.cs that is the configuration file here let me create a method I will call that apply migration what exactly do I want to do that I want to get the application DB context service here and check if there are any pending migration if there are then I want to apply them for that we will have to write a using statement and I will create a variable with the name of scope app dot services dot we will create a scope there will basically get all the services now from this service we only want the required service of application DB context so I can say variable underscore DB is equal to scope dot service provider there we have a method get required service we want the surface of app DB context that will give us the application DB context here and on that application or app DB context we can check if underscore DB dot database there is a method get pending migrations dot count so if that count is greater than 0 that means there are some migrations that have not been applied to the database in that case we will say underscore DB dot database dot migrate that will automatically apply all the pending migrations to the database we need to invoke this method so in our pipeline here we can add apply migration and with that whenever the application is restarted it will check if there are any pending migrations it will apply them if there are not it will ignore that when we run the application it should have applied our migration let me switch back here and perfect with that we have added the logic to automatically apply any pending migration our database and model setup is looking great now we can finally add a controller in our API we have a default weather forecast controller let me delete that along with the weather forecast model I will add a new controller here and it will be an API controller empty controller controller name let me call that coupon API controller default route here will be API forward slash and we have the coupon API that is the controller name first endpoint that I want to implement is retrieve all the coupon and display them in order to retrieve our record we will be using Entity framework core and for that we need appdb context using dependency injection so I will have a private read-only app DB context here let me call that underscore DB and inside Constructor appdb context I will call that DB and underscore DB is equal to DB now the end point here will be an HTTP get endpoint and let me call that public return type let me keep that as object and here it will be a get request in there we will add a try catch block inside the dry Logic the return type will be an i enumerable off coupon call that as obj list we have to retrieve that from underscore DP dot coupons dot to list we will retrieve that using Entity Framework that looks good here and finally we will return the obj list here if nothing works here we have exception we will return back null that looks good forget all let me run the application and see if that works and perfect we have the end point using our Swagger documentation if we try that out perfect we can see both the coupon here so that looks good I can copy this endpoint paste it here next endpoint will be if I want an individual coupon based on the ID here route I will have to Define that we expect an integer ID if you do not write it then things will not work and let me show that but based on the ID we need to filter here so we can say first here where U goes to U dot coupon ID is equal equal to the ID and return that back it will be a single object and not a list save that and let me run the application the Swagger documentation will display an error message that is because when Swagger is looking at the endpoint here it will basically think that hey both of them are a get request it is not able to differentiate that hey this get request requires an integer ID if you want that to be explicit you have to define a route here and in that route I have defined here that ID will be provided which is an integer with that if you restart the application now Swagger will be able to tell difference between both the end points and if we try that with an ID of 1 that works if I add an ID of 3 you can see we do not receive any response back because that is an invalid ID so perfect as long as ID is valid we will get that bank with that we have to get all and get individual coupon endpoints in our API we have two endpoints and in those end points we are returning different things but what if we want to have a common response for all the endpoints in our website like right now if there is any error we cannot return that back we are returning the coupon dto if we want something to be common for all the API endpoints in our microservices that way whenever an API or rather multiple apis are being consumed by an application it can be shared that okay the response that I will get from API will always be in one object format and that will be a great architecture for our API response what we will do is in coupon API dto let me create a new class I will stop the application here let me add that I will call that response dto when it comes to any response here what are some things that are needed first is the object itself it can be a coupon it can be an i enumerable of coupon if you add multiple other tables it can be those object so we will not know exactly what will be the return type so I can call that an object and I will call the property as result that will have the final response like a list of coupon or an individual coupon along with that we will add a Boolean flag which will denote if the request was successful or not and I will add a string here that will be message so let's say if there are any errors or if there is any success message we can display that in that variable these three properties will be sufficient and that way we will have a common response for all of our API now we need to return response dto in the coupon API controller let me create a private response dto [Music] and we can initialize that in Constructor when we are returning here we can set the underscore response dot result that will be the obj list and at the end here we can return back the response the return type here we can modify that we now know it will be of the type response dto and that will apply for both the endpoints if there is any exception here we can set the is success to be false and message will be the exception Dot message one more thing that we can do is inside the response dto is success default value we can set that to be true and for message we can make it an empty message and perfect that looks good let me scroll down and modify it here we will have underscore response dot result we will have an obj here let me rename that and in the catch here we will copy and paste that return will be underscore response perfect that looks good let me run the application and validate to make sure everything is working in the ID here if I enter two perfect we have result is success is true if I add something invalid perfect the success is false here and message we have sequence contains no element let me try the get all here and that looks good with that we have added a common response dto and that will be the return type for anything that we will return from our API right here on the top you can see it is basically clustering all the main methods but I do not like it that much I prefer to keep things simple like it was but they have modified that with the new version of Visual Studio I hope there will be a setting to turn it off but right now you might have to deal with that so fingers crossed if they update that but next thing that we want to work on here is when we are returning something here you can see we are returning the coupon object like here we have a list or I enumerable of coupon and down here we are returning the coupon itself we have added ttos in our project we should not return the coupon or the data object itself we should return the dto what you might have to do here is you might have to do a manual conversion like here you can say coupon dto is equal to new and then you can map the individual like coupon ID is equal to obj dot coupon ID next one coupon code then we have discount amount and we have minimum amount once you do the conversion you can return back the coupon dto right now it is looking ugly think about if you had to do that for all the endpoints in all the micro services that will be a nightmare thankfully we have Auto mapper and for that inside the project I will add a new class file let me stop the application you can do all of this mapping configuration directly in program.cs but I like to separate it out that way the program.cs is not too clustered I will call this file as mapping config here and there we want to add the configuration for Auto mapper we will add a static method here and return type will be mapper configuration that is inside Auto mapper let me give it the name of register Maps here and inside there we want to add a mapping that hey if you get a coupon dto you should be able to convert that to coupon and vice versa now with auto mapper it is pretty smart as long as the property name are exactly the same it will automatically do the mapping and you can see we have the exact names and coupon and coupon dto so that should work we will create a variable here mapping config is equal to new mapper configuration and there we will Define the option so config dot create map there we have to Define what is the source and what is the destination we can say coupon dto will be the source destination will be the coupon object we can create the other mapping where we want to map from coupon to coupon dto finally we will return the mapping config that way we are telling Auto mapper that you might have to create a mapping from coupon dto to coupon and vice versa with that we have one more thing when we add the mapping config we have to register that in our services so right here we will be creating a mapper object call that mapper is equal to on the mapping config we have the method that we created register maps on there we have to create the method create mapper once we create this mapper here we will have to register that to our service so Builder dot Services dot add Singleton that is the lifetime and we will register our mapper there finally we want to use automapper using dependency injection for that you will have to add the line Builder dot Services dot add Auto mapper and there you have to pass the app domain dot current domain dot get assemblies that is the basic configuration that you have to do to add Auto mapper to your services but with that configured now you can easily inject Auto mapper in your controller we will do that using dependency injection create a private eye mapper and we will have imapper here call that as mapper and underscore mapper is equal to mapper where we have to do the mapping here we will say underscore mapper dot map what is the return type that we want that will be the coupon dto and here we can pass the obj we will cut the result here paste it here and perfect what the single line will do is it will automatically convert the obj that is of coupon type to coupon dto and return back pretty smart we need to convert an i enumerable of coupon to an i innumerable of coupon dto we can use mapper here dot map what is the return type that should be an innumerable of coupon dto add that here and we need to pass the source that is inside the obj list right here perfect with that if we run the application everything should work the same let me try that here and perfect you can see the response is valid and with that we have added automapper to our project we have added two endpoints when we typically retrieve coupon we might have situation where we want to retrieve coupon based on the coupon code we will leave the ID here but we will add one more get configuration where we want to get coupon based on the coupon code I can switch back here let me copy this HTTP get method paste that one more time the route we will have to update that so let me add a new method name here get by code and there we will expect a string which will be the coupon code let me modify that here and rather than first here I can do first or default it might be empty we will say dot coupon code dot to lower is equal equal to code dot to lower that way coupon will not be case sensitive once we retrieve the object we can return that back if I save that hot reload will kick in and perfect let me try that if I enter 12 the result is null here but let me try 10 off and perfect it returns back now if the obj is null here if obj is no then we can set the is success to be false with that if I go back and if I write 12 here success is false and that looks good if you do not want to add this you can only use the first here it will throw an exception we are catching that and that should also work let me see that perfect you can pick whatever route you want get is looking good here we need to add a method to create a new coupon copy and paste that again HTTP post to create we do not want any route there we can rename the method here to be post when we are creating we will receive something in body so from body and we will receive a coupon dto when we receive that coupon dto we will have to convert that back to a coupon only then we will be able to add inside the underscore DB let me show you that if on underscore DP dot coupons there is a method to add an entity in Entity framework code and here if I Pass coupon dto it will not work you can see it cannot convert from coupon dto to coupon so here we have to pass the coupon itself we will have to convert that so coupon obj is equal to underscore mapper.map I need to convert that to a coupon object and we will pass the coupon dto when we create we will pass the obj and with Entity framework core when you create update or delete anything you have to save the changes if you do not save the changes then this will not work in line 80 here we are telling Entity framework that hey you have to add this record in coupon table you have to add this record in coupon table but on line 81 when we save the changes at that point it will go to the database and create that record so it is important to save the changes once you do that when we return back we will return dto and not the coupon object so we can map the obj back to coupon dto if I save the changes I go back Arc reload kicks in I do not have to restart the application and that is great we do not want the get here we want to try the post let me add some dummy discount amount and minimum amount post that and perfect you can see the success is true here if I go to database great that coupon was added after that I quickly want to add two more endpoints one to update a coupon which will be HTTP put here call that as put we will receive the coupon dto after we convert the object to a coupon object rather than add in Entity framework core we have the update method and that will do everything for us it is pretty smart based on the ID in the obj it will find that coupon record and update all the other fields that are provided right here after that let me copy this paste it one more time for HTTP delete rename that to be delete when we are deleting I do not want the complete coupon I can only get the ID that user wants to delete based on that IDE we will have to go to database underscore DP dot coupons whoops dot coupons DOT first and U goes to U dot coupon ID is equal equal to the ID we retrieve that coupon and on coupons with Entity framework we have a remove method that will remove the object we save the changes we do not want to return anything back here that looks good let me go back our application is already running let me try to update first the coupon ID is three let me make sure yep I will update everything to be 33 here let me go down that works if I double check here perfect let me write a link now delete the coupon ID 3 success is true and let me see here great with that all the credit functionality for our coupon endpoint are working as expected now we're going to work on a front-end application that will be consuming the coupon API we have created a folder for that if you right click add a new project in there that will be the web project when we are working with the front-end project to consume our API we can go with Razer project or an MVC project or even Blazer project for this course I will be using asp.net core web app with model view and controller that will be MVC for name of the project let me call that as mango.web and let me create that we do not want any authentication type keep that as none and let me create perfect with that we have created our web project where we will be consuming the coupon API we want to consume our API in the web project but when we consume any API we typically have to write few things like what is the type is it a get post put delete and then we have to specify the URL along with some data if you are posting some record like in the API here where we have the coupon API you can see sometimes we can pass the ID in url but sometimes we have to pass the object in from body and for that similar to the response dto that we added in coupon API we will have to create a request and a response dto in the web project I can copy the response dto from here and paste it in the models folder well let me copy and paste that again that did not work and then if you open that we will have to change the namespace here to mango.web dot models now based on the tab coloring I can see that yellow one is the web project and the blue ones are the API again I have enabled that right here colorize document tab by project you might be thinking that hey we have a response dto that is common in two project why don't we create a third project where we have all the common models now that might seem okay for the course that we are doing but when you are building a real world microservices architecture all of the project might not be in the same solution like if you have seven different micro Services the services might be in their own Solution by themselves and at that point sharing the common model folder is not something that is common and because of that even though we will have to copy the models from API in the web project I will do that manual approach because that is the real world scenario which you will encounter because web project will have a different models that are inside that project and coupon API right now even though it is in the same solution but in real world it might be in a separate Solution by itself so keeping the models isolated to their corresponding project is important when you are building microservices now we have the response dto that we will get when we call an API but we need to create a model here which will be request dto and that will have everything that is needed when we are sending a request right now let me add a verb right now let me add four properties in there first one here is API type that defines if it is a get post put or delete request then we have the URL and data will be populated when we are posting or updating some record finally we have added a field for Access token but we will not be using that in this section later on when we add authentication and authorization we will see how to use access token now rather than having a string for API type let me create an enum for that in the web project here let me create a new folder for utility and inside there I will create a class file static details and there let me add an enum I will give that a name of API type we will add get post put and delete save that here and then the type here will be API type if you press Ctrl dot we can add the using statement and the default one will be API type dot get that way we will avoid any mistake when we are using an enum but with that we have a request dto and response dto in our project we have the request and response dto let me close all the tab from the web project we will be calling the coupon API when we add more apis in the project that particular service will be responsible to call all the other API endpoints and for that we have to make it more dynamic in the web project let me create a folder of service and in there create a new folder for I service where we have the interface we will add a new item the interface name let me call that ibase service and let's think about what will be the method that we will create here let me call that method as send async and when we will be making any API calls in the parameter here we will be passing the request dtl that we created that looks good for the parameter but what will be the response that we will get back from the API if you remember in coupon API we have all the response that is aligned with the response dto we want to make this method asynchronous let me add task there and that looks good and with that the interface is looking good let me implement this interface in the next video we need to implement the interface for our base service inside the service folder I will add a new class call that page service that class will be implementing the IPS service interface let me do that here and I will add the async keyword when we have to make API calls to let's say coupon API this time we need the HTTP client previously what we used to do is in the Constructor here we used to inject the HTTP client but with the newer versions of dotnet core they have moved away from HTTP client and now the preferred route is using ihttp client Factory so let me inject that it will be a private read only field I HTTP client Factory we will get that with dependency injection now right now we have not configured our application with the client Factory I will do that later on but right now I have directly injected the client Factory and let's say it will give us the correct implementation of what exactly we want and the only thing that we want to focus on right now is writing the method to make that API call using the client Factory from the client Factory we have to create a client itself and that will be on HTTP client Factory we have a method create client and there we can give it any name let me call that mango API when we are making a call we will be using the HTTP request message and we can provide or configure options on that message one of the important aspect is on message dot header we will say that we are accepting application forward slash Json now in future when we add authentication we will also have to add that token here so let me add that in a comment then on message we have something called as request URI there we have to specify the URL that we will invoke to access any API if you examine the request ETO we have that right here how that will be populated do not worry about that right now we have to assign that right here so new URI and I will pass the request ETO dot URL then if it is a get request we are okay but if it is a post request or a put request we need to serialize the data that we receive here and add that to message dot content we first have to check if the request dto.data if that is not null then we have to serialize for that I will say message dot content is equal to new string content and there we will use Json convert we will have to add the new get package newtonsoft.json let me add that and then we have serialize object there I will pass the request dto dot data when you are serializing you can also Define the encoding so we can say encoding utf-8 and that is application forward slash Json that looks good for the data we have the request message when we send that we will be getting a response let me create a variable to hold the API response now one thing that we have to set here is in the request ETO we will get the API time based on that we will have to configure the message Dart method so if it is a get here we will configure that and so on rather than if else condition a switch case would be a better scenario so on request ETO dot API type we will be adding case we have that in static detail so if that is a get here let me remove this and add a using statement perfect if it is a cat here we can say message dot method is equal to http method dot get but get let me keep that as the default one so let me change this one to be post here that looks good we will add a break condition copy that and paste it about four more times we will have the delete here change it here next I will have the put request and finally if nothing is defined we will have our default case here which will be the get request and I should have left the brick command there perfect based on the API type we are setting the message dot method final thing that remains is to send this and get a response back response we will store in the variable API response and to invoke or send that we will be using client dots and async pass our message inside there when we get the response back we know from the API we will be getting a response dto we can always deserialize that but before we do that we can check the status code of the response that is received so let me add a switch condition here on the API response we have something called as status code the first case that I want to handle here is HTTP status code dot not found right now we will handle all the exception or error cases first and let me add the using statement if it is not found we want to return a new object and that will be of the type response dto we will set its success to be false and we can set the message here to be not found copy that and paste it about three more times here next status code that I want is forbidden then unauthorized and internal server error which is 500. we will also add the corresponding error message here and that looks good but if it is not in one of those faulty scenarios we will add the default condition inside there we have to retrieve the content from API response so we can say variable API content is equal to a weight API response dot content dot read as during async and then we will deserialize that to a response dto we will have a variable here let me call that API response dto is equal to Json convert dot now we will be deserializing the object into response dtl I will pass the API content there and whatever VT serialize we will return that back that is perfect for our condition here we can add this inside a try catch block here and if any exception is caught here we will basically return a new response dto we will set the message with the exception its success will be false I believe with that the method that we have to send async is looking good the only way we will be able to test is the only way to test everything is once we wire up all the service for coupon then we can say this in action we have the base service right here we need to call our coupon API and for that we will be creating the coupon service in the service folder let me create a class file it will be an interface I will give it a name of I coupon service when we are working with the coupon service we need the coupon dto because if we are getting all the coupons what will be type of that model that will be coupon dto and like I said before we will not be sharing project we will rather create the coupon dto inside the web project so let me copy coupon dto from the coupon API and paste it where we have the model right here modify the namespace to be mango dot web dot models that looks good after that we have to work on the coupon interface right here what will be the return type when we invoke the API that will be response dto and it will be async method so let me add task there response dtl let me make that nullable first one let me call that get coupon and here we can get that based on the coupon code copy that and paste it few more times here next one let me call that get all coupons and let me add the async after all the methods when we are getting all the coupon we do not need any parameter I can close that and let me copy this paste that few more times here I will have get coupon by ID here where we will pass the integer coupon ID next we need to create or update a coupon so we have create coupon async when we are creating or updating we will pass the coupon dto for update as well I will pass the coupon dto last one will be delete coupon async when we are deleting we only pass the ID if you are confused about what will be the parameter here you can always open the coupon API controller and you can notice that when we are getting all we do not have any getting individual we have the ID get by code we need the code here when we are creating we have coupon dto when updating we have coupon dto and delete we only have the ID let me make this a put request and that looks good with that we have created the interface for our coupon service we need to create the implementation for I coupon service in the service folder let me create a new class file give it a name of coupon service that will implement the I coupon service and here we need the base service because that is the main class that will be responsible to handle any HTTP request and it does not matter whether it is a get put post or delete this will be the base implementation for all of our services if I go back to the coupon service here we need to inject that using dependency injection after that let me implement the interface and all the methods right now we have not added the base service or coupon service in the startup or rather the program.ces class file we need to inject that first only the independency injection will inject That Base Service when we are requesting it in any other class now when we configure the coupon service we need the URL of our coupon I can hard code that in the program.cs but an ideal approach is to have that inside app settings and I will create a variable to store coupon API base that will have the base URL for coupon API then where will we store the URL that will be in app settings.json right here let me create a new section with the name of service urls and that the first one that I want is coupon API and we need its URL to get that URL we can either run the project or we can go to launch settings.json and coupon API and we have that right here make sure you get the https one paste it right here in the app settings of web project next question is how will we populate this particular coupon API page with the app settings that we have we will do that inside program.cs of the web project yellow color is the web project so that way I can easily differentiate that right here we need to populate static detail dot coupon API base we have Builder dot configuration and there we can Define the key name key name if I go back first we have the section name then we have to write a colon here and we can pass the key name which is coupon API that will retrieve the value and assign it when the services are being configured next thing if you go to Base Service scroll up here we are injecting the ihttp client Factory but we have not registered anything in the services in order to register the HTTP client Factory that we are using with dependency injection in program.cs right here we will be adding Builder dot Services dot add HTTP context accessor but the main thing here is the add HTTP client once we add the HTTP client here then we can configure that coupon service will be using HTTP client for that we will say Builder dot Services dot add HTTP client and the interface is I coupon service implementation is inside coupon service that looks good for the configuration but right now we have only configured the HTTP client we have not configured in our application that hey when we are looking for a ibase service implementation you need to get an object of the base service and same applies true for the coupon service to add that we will have to register on Builder dot services and we have to define the lifetime which will be scoped we have the coupon service and before that let me add builder.services.addscoped I want to add the ipage service with that we have registered both the base service and coupon service and also configure the HTTP client right here with all of that configured what we have to do next is Implement our coupon service we need to implement the coupon service first method that we have here is create coupon but let me start simple we have the get all coupons right here for all of the methods here we need asynchronous keyword let me add that before we proceed further perfect now where we have to get all coupons we will add the return statement a weight on the base service we have the root method which is sent async there we need to configure the request dto with the correct parameters we will create a new request dto object here and we need to populate API type this is a get request so SD dot API type dot cat next parameter here is the URL itself that is inside static detail we have the coupon API base and after the https we need to add the API and coupon now let me go to app settings here you can see we do not have a forward slash after the port number that is why right here we will have to add a forward slash but with that it will get all the coupons that looks good let me go to get coupon async there we have to pass the coupon code when we are getting the coupon code let me open up the API controller in coupon API and where I have that right here I have given a special name Cat by code we will copy that go back to our coupon service and right here after coupon we will add the getby code and then we need to pass the coupon code we will add plus and the coupon code when we scroll down we have the get coupon by ID let me copy and paste it here and that time we do not need the custom name here we only have to pass the ID there we have update here but before that let me copy this remove the extra semicolon there and we have delete coupon for delete the API type will be delete here and the URL if I go back where we have delete we are passing the ID so what we have here is perfect now what we are left with is create and update with both of them we have to pass the coupon dto it will be either HTTP put or HTTP post let me copy one of the return statement here without the extra semicolon paste that for create the API type will be post there and next we have something called as data that data is nothing but the coupon dto itself when we go to the base service we are already serializing that so we can directly assign the object here we will serialize that before we send the request URL here we do not need any ID we only need API and coupon looks good let me copy and scroll down to update here and the API type here will be HTTP put that looks good with that we have implemented all the endpoints for the grad operation in coupon service we want to see our coupon service in action but let me close all the tabs here and when we are working with multiple project if I run the application right now it will only run the coupon API I want to run both coupon API as well as the web project we will right click on the solution here and we have configure startup project we will select multiple startup project and we will start both the API as well as the web application with that configured let me hit the Run button and perfect it starts the API and in the background we have the web project right now by default if you click on the hard reload icon here you can see hot reload on file save is enabled because of that when I save anything it will automatically reload the application if this is not checked make sure to select that it will help you when you are testing or debugging few things but before anything I want to change the default bootstrap theme that is there in the web project I will be using a boots watch theme so let me search for that here and if we go to themes here and if you scroll down you can see we have multiple themes right here for our project we will be using the Slate theme Here so let me download that and once you download let me open that file copy that we will go back to our project and in the web project WWE root folder lib we have the bootstrap default theme let me overwrite what we have so delete everything in bootstrap.css and paste what we copied if you scroll to the top here you can see the theme is slate here and then if you go back to the application nothing is updated that is because if we go back to the project and if we open the master page that is underscore layout you will notice we are using the minified version we updated the dot CSS so let me replace that and go back here perfect things are getting different before we fix the header here I want to add a drop down so let me search for bootstrap 5 go to the documentation here search for nav bar and we have the drop down here let me copy the LI element go back to our project paste that right here perfect looks good let me save that and if I go back great we have the drop down you can notice here is drop down is in blue color and that is because in underscore layout we have a custom CSS behind that where we have added a color for anchor tag we can remove that if you are not aware of this custom CSS it is basically a CSS that is bounded to the layout page and you can see the name is exactly the same we can remove that and if we go back after that perfect we do not have that blue color anymore let me make the header dark here we will go back to underscore layout and let me see where we have the navbar light I will make that nav part dark remove the background white and Border bottom save that let me see perfect where we have the text we will remove text dark because we have the dark background we do not need that anymore looks good save that here perfect much better lastly the footer here let me modify that as well we scroll down we have the Border top let me remove that and right here I will add made with love by.net mastery perfect now while we are here let me add bootstrap icons typically I used to love the font awesome icons but with the ease of bootstrap icons these are becoming my favorite if you scroll down here we have the CDN right here you can see there are many icons that are available to use in our project it is simple to get started all we have to do is an underscore layout paste that CDN right here then if we go back here and if we search for an icon let's say heart icon and we scroll down we have the hard fill copy that and let me paste it here go back to the browser great our footer is looking great and the header and navigation everything is aligned with the Dark theme with that configured we will shift our Focus to consuming the coupon API we need to call our coupon API right here let me go back to the application and right here in underscore layout where we have the drop down let me change that to be content management and the first link that we have here rather than H Raph here we will go to ASP controller of coupon controller ASB action will be coupon index we have not created that but we will do that very shortly save that and if I go back here perfect that looks good let me create our first controller we will do that in the controllers folder I will have to stop the application add a new controller now this controller will be an MVC and not an API controller because we are working with the web project I will give it a name of coupon controller we will go with the empty controller and configure everything right there in order to invoke the coupon API we have that in the coupon service we have already configured that independency injection so let me consume that right here we add that in the Constructor here and then the index action if we go back to underscore layout I am calling that coupon action so right here I will rename that to be coupon action and what will be the return type coupon service if we go there they are asynchronous method so here we will add the async keyword task of I action result that way the action method can use a weight keyword for this particular view here we want to display all the coupon we will have list of coupon dto and let me call that list is equal to new we will be getting a response dto from our coupon service let me call that as a response and that will be await underscore coupon service that we have the get all coupon async that should retrieve all the coupon once we get the response we can check if response is not now and we can also check the response that is success if that is true then we can populate list from the response.result if we do F12 here that is an object we will have to deserialize that object using the Json convert we will say Json convert dot deserialize object and what will be the type that is a list of the coupon dto let me add that and from where we will deserialize that before we deserialize we will have to convert that to a string and inside there we will pass response start result once we do the conversion if everything is successful our list will be populated and when we return back to the view we can pass that list we have done quite a few things we have added Base Service we have added coupon service and then we added the coupon controller where we are calling the coupon service now let me run the application but before that add a debugging point and let me see if this actually works now right now I will tell you it will not work because I have intentionally introduced a bug there if I press F10 in the response here you can see the message not found I want you guys to debug and find out what is going on here why did we get the S success to be false and the message as not found I hope you were able to figure that out what I did intentionally is in coupon service you can see the route is API forward slash coupon but if we go to the end point which is the coupon API there when we look at the route here we have the controller name controller name will be coupon API and not coupon to fix that what we can do is right here we can append coupon API and that will work but I do not like that approach when we actually have to give a route name if you give it a right name of coupon API and then fix the coupon service that is okay but rather than giving it the controller name I like to give it a hardcode name of the route like this that way what will happen is in future for some reason if the controller name has been updated then you will have to notify all the client application that hey my route is updated if you do not do that you will have to remember to change the route to be the coupon API right here but to avoid all of that when you start the controller you can always Define a hard-coded route that way that route never changes even if you update the controller name I will call that API forward slash coupon and that is what we have in the coupon service you can see in all the places we are using API forward slash coupon with that configured if I run the application it should work if it still does not work we will debug and see what is going on examine the response here and great success is true here and we have the result let's see if it deserializes that and great we can see both the coupons and the coupon index is working as expected now before we do anything else we will have to create the coupon index view to display all the coupon we need to create the view for coupon Index right click on that action method we have ADD view it will be an empty view make sure to give it the same name that is coupon index add that now rather than typing the HTML and CSS I have provided all of that in Snippets right here make sure to download them from.net Mastery and once you download that in the Snippets folder Section 3 we have the coupon index View copy that and paste it right here if you save that and run the application let me show you what we have by default we go to coupon here we go back to the view and perfect you can see I have a table layout here but there are no records we need to add a for each Loop and we have to iterate through the model that we are passing from where is that the coupon controller right here we are passing the list here for that we need to define the model of our view that will be a list of coupon dto or an i enumerable so right here we first have to Define model that will be an inumerable of coupon dto next thing we scroll down we have the tea party here we need to add a for each Loop and iterate through our model we have the header here but in the body we will add for each Loop we will say variable item in model when we are using the model at the top here it will be a lowercase but anywhere else it will be a capital m we will add the closing bracket here that looks good and right here first let me see what we have coupon code so item dot coupon code next TD we have the discount amount we need to convert that to a string so item dot discount amount dot to string here change that to the currency format and let me add one more bracket perfect looks good we have the minimum amount that is also a currency let me add that here perfect if I save that hot reload should kick in and perfect we can see both the coupon and with that our coupon index is looking great next thing that we want to work on is creating a new coupon we will go back here and if I scroll up we have the anchor tag right here we need to create an action method in the coupon controller let me close the coupon API and everything else it gets confusing super quick so make sure to keep your tab up here super simple we will add a public async action method that will be task of I action result name of the method to create a coupon I will go with the model name which is coupon and what is the method responsible for that is create by default in the get endpoint we will return back to the view and keep things super simple we need to add this view stop the application right click whoops add view empty View name will be coupon create perfect if we go back to our snippet we have the coupon create View copy that and paste it right here now what will be the model of this View from the controller we are not passing anything but we know we will be creating one coupon so right here the model will be coupon dto itself we will be working with only one coupon so we do not have an eye innumerable there after that let me modify the view here let me run the application to see how that looks when I go back coupon if I click create new coupon I need to redirect there so right here we will add the ASP action and that is coupon create I am not adding the controller name because we are in the same controller our reload should have kicked in and yes it did we have the create coupon and that looks good we have a padding here but that will be used for label that we have right here first one let me display coupon code scroll down we have the discount amount and we have the minimum amount if I save that whoops I have a spelling mistake there perfect that looks good for validation we will be using validation scripts partial that is right here we have the jQuery validation we will scroll down at the end here add a section script and we will use the partial tag with validation scripts partial make sure the name is exactly the same or else it won't work then let me go back up here where we have the input let me add esp4 this one is for coupon code that looks good and then let me add a span for validation ASP validation for will be coupon code class will be text Danger I will copy both of them and let me paste it in the other two places we have the discount amount copy that and we have the minimum amount copy and paste that perfect let me save that and if we go back hit the create button perfect we have the validation our view is looking great for create coupon back to list is not functional where we have that we want to go back to the action which was coupon index if I save that perfect it is functional in the next video let me work on what should happen when we populate Fields here it's a number and hit the create button we need to post our form what I can do is in the form here I can Define ASP action will be coupon create that is where we want to post the form we need to work on the post action method for coupon create copy the get action paste that one more time here this will be HTTP post when we are posting We will receive a coupon dto we can call that model that's also fine first what we have to check if model state DOT is valid we have the client-side validation right here but we should also validate on server side that all of the default validations are good if they are then on the coupon service we have the create coupon async that we need to invoke let me copy this paste it here method that we want to invoke is create coupon async and we need to pass our model if that is successful we can redirect them back to the index action rather than magic string here let me use the name of coupon index and if the model state is not valid let me return back to The View with the model with that let me save all the pages here go back and let me try to create it redirects us back to the index and coupon was actually created successfully and if I switch to SQL Server mango coupon let me see we should have three records great with that create functionality is looking great next thing we want to work is on the delete functionality when we work on the delete functionality we need to pass what particular coupon user wants to delete so the route will be something like coupon delete and then maybe the ID like 12 2 or whatever it is let me go back to the application in the controller here copy this coupon create paste that again rename the action method to be coupon delete in the parameter here we will receive the coupon ID now how do we pass this coupon ID from the coupon index where we have the delete icon well in the anchor tag here we will Define the ASP action and that let me copy the name coupon delete past paste it there when we are calling this we want to pass the coupon ID for that we will be using ASP route tag helper with that we can give it any name the variable name that we expect here is coupon ID so that is what we will write here and that ID is inside item dot coupon ID with that let me copy this add a debugging Point here save all of that if I hit the delete icon perfect we get the coupon ID we do not have the view so let me add that but before we do that when we are loading the view to delete a coupon we need to display all the coupon details and for that we will have to get coupon buy the coupon ID we go up here well I can copy this right here not this let me copy where we are deserializing the object paste that here and the method name will be get coupon by ID async we need to pass the coupon ID there if we do get a response back we will deserialize that but this time it will be of the type coupon dto let me call that coupon dto call that as model and if it retrieve that we will return back to The View with that model if we do not get anything back we need to return a not found you can have a 404 View and return that but we will keep things super simple for now let me copy the action method name and create that view I will stop the application empty view here now this view will be exactly same as coupon create I can copy everything paste it right here model will be the same change that to be delete coupon and the action name will be coupon delete we do not want any validation here and all the fields will be disabled let me add that back to list looks good here it will be delete we can display BTN Danger perfect we do not want any validation and that looks good one thing that you can add here is in the input tag asp4 we can have the coupon ID as the hidden property perfect I believe that looks good let me run the application and see if everything is functional we go back to the coupon try to delete this one and great that looks good now we need to work on the delete action method copy this paste it one more time here this will be HTTP post here and we will get a coupon detail when we are deleting we have delete coupon async that time we only need the coupon ID so let me pass coupon dto dot we have the coupon ID there if that is successful we can redirect back to the index action method copy that line paste it here if that is not successful we can return back to The View with the model which is coupon dto with that I believe everything should be functional let me hit the delete button and for some reason it is redirecting me back and you can see it is not working now we need to debug and find out what is going on when we are trying to delete a coupon it is not working before we debug that together I want you guys to give that a try and see if you can figure out why that is not working I hope you were able to figure that out but if not let me do that together whenever something is failing rather than adding a debugger here I will add that in the base service that is where all the magic happens we have the switch case here let me add it there write delete and let me press F10 this is the get that is okay we hit the delete icon it should go to http delete that looks good let me examine the response well we have method not allowed you can see the URL it is going to is API coupon and then the ID let me see what we have in the coupon API controller we scroll down to the delete we have the ID but we do not have the ID in the route that is why it will not work right here we need to Define that hey there will be an ID in the route and that is of type integer with that saved let me remove the debugging Point here continue and it deleted automatically thanks to hot reload let me try one more and if we delete that perfect you can see that is functional now with that the current operation are functional with coupon but I have not implemented the update functionality if you want you can implement the update functionality it will be straightforward but I do not want to do that right now and in the later videos you will understand why I did not add the update functionality for coupon right now what we have for our coupon is looking great before I end the section here I want to implement toaster in my web project toaster if we scroll down here in the demo you can see it displays a nice toaster notification I want to add toaster if something fails or if something is successful adding that is super simple we need to add the CDN so let me copy that go back to my project here and let me close all the tabs we will do that in underscore layout in the web project I copied the JS first I will add that right here script SRC paste that here and let me scroll up next I will be adding the link real style sheet href let me copy that and I will paste it perfect toaster has been configured then rather than adding all the toaster notification in individual places let me do that in the main underscore layout I will create a new partial view whoops not what I wanted let me go back and bring that back to what it was in the shared folder stop the application I need to add a view I can copy the validation scripts partial paste that again I will rename that to be underscore notifications for notification I like to use temp data temp data is something where you assign a value and that only stays for one request to show you an example here if we go to coupon controller here the response is successful in the else part that means the response was not successful for that we can add temp data here in success well this will be of error type and there we need to display the message we have that in response Dot message we can use that let me add a null check here and I will copy this else condition paste it in the other places perfect so if the response is not successful we will assign the message and temp data of error in here we can check if that is not now then we can display toaster notification we will add the if condition and we can check temp data in the view as well let me check the error here if that is not now then we will need jQuery and toaster.js before we display the toaster notification jQuery is already included in your project so you can add that here and then where we added the toaster let me cut that and move that right here we will add a section for script here type will be text JavaScript the default one at the closing script and within there we have toaster notification let me go back and see the usage right here copy that paste it here we have the edit one and we need the message here that message is inside temp data with the key of error let me copy this paste it one more time if temp data of success has some value we will display that right here with success that looks good in order to test that where we have the coupon API I can change the route here to something else and let me see what happens we will go to coupon that did not work let me see why in the coupon controller where we have the coupon index let me debug that it did set the temp data whoops I think I know why it did not work we added the underscore notification but we did not add that in underscore layout where we have the render body we need to add that partial View name is equal to underscore notification that way on all the pages we will have support for toaster with that configured let's go back and whoops refresh is not working let me restart and it will be notifications I noticed we have plural here let me make sure the spelling yep that looks good I need to save everything here go back coupon and it still does not work if I press F12 here we have the toaster is not defined and that should not be the case let me go back here whoops they have an invalid.js there we can go to CD njs directly and try to find out the toaster there we go copy that script tag and we need to paste that right here in both the places that was art that on toaster.js they had the invalid CDN but with that let me go back to the web project refresh and great we see the not found toaster and that is looking perfect so with that we have configured toaster in our application but before you forget make sure and make sure to go back and change your route back you can also add more toaster where you have the success route like let me copy this and coupon create HTTP post we can set temp data of success here coupon created successfully copy that for delete and coupon deleted successfully let me see if that works we will try to create a new coupon well we already have one let me try to delete and great our toaster notifications are working as expected we have coupon API and that is working as expected when we think about a microservice architecture we need some kind of authentication to make our API endpoint secure and only the allowed user with correct credentials can access our API endpoints and for that security we will be using.net identity and we will create a new API in our solution let me close all the tabs here in solution where we have our services let me right click add a new project it will be an API here I will call that mango.services.auth API let me create that perfect our project has been created but before we do anything here we need to install nuget packages because we need the.net identity and authentication packages what I will do is we have few packages that we have installed in the Groupon API we can right click there select the edit project file copy all the packages from there and we can paste it in the project file of auth API remove this and paste all the packages perfect that way if we examine the dependencies we have all the basic packages with Entity framework core and Auto mapper in the auth API if we examine the dotnet identity we are using the port number 7002 in our architecture let me add that in our project as well we go back here or the API launch settings.json and rather than 7015 we want 7002 perfect that looks good now the.net identity is a package that will create all the identity related tables automatically with Entity framework core but for that we need to set up Entity framework core and DB context in our project for that we need the appdb context and we can copy that data folder paste that in the auth API to save some time you will have to open the appdb context and we will change the namespace here this will be auth API and not the coupon API we do not need anything with the coupons here let me remove all of that here and perfect now typically when you are working with Entity framework core we only needed the DB context but here we will be using.net identity in order to use identity for authentication and authorization you will have to implement from something called as identity DB context if you press Ctrl dot we have to install the new get package of microsoft.asp.net core dot identity dot Entity framework core that package has been installed but if you right click here manage new get packages I do not believe it will be dotnet 8. I was correct we will select include pre-release and update that to be the same version perfect that looks good inside the app DB context where we added the identity DB context we can Define the D user right here you can also see the default user is identity user so let me write that for now perfect that looks good next thing that we have to do is configure program.cs file let me copy that from coupon API to save some time there we do not want Auto mapper right now we only want the DP context let me paste that here and we scroll down where we have apply migration let me copy that paste it down here and I will execute that perfect now we know the auth API is responsible for authentication and authorization so in the pipeline before authorization we have to add use Authentication when it comes to adding in the pipeline authentication must always come before authorization if you add it after authorization things might not work we have the appdb context here at the using statement and perfect right now we have only configured the DB context in our project but in this project we have something special we have to tell Entity framework code that hey we will be using the.net identity and we will be using Entity framework core where we have the DB context with the.net identity that is how it will know that okay I have to use the DB context to create all the identity related tables defining that is super simple on Builder dot Services we have something called as ADD identity and there you can Define two things what is the default user that is identity user that comes by default on top of that you have to define the role we will be using the default identity role for now do not worry about the complexities I am using whatever is default right now when we modify things I will Point those out but right now we are setting up the default identity on there we have to add the Entity framework stores and we have to define the DB context that will act as a bridge between Entity framework code and.net identity finally we will be using a default token providers there with that we have configured identity in this API project but now you might be thinking what exactly will happen because of this configuration that we added inside the program.cs file in order to see that let me open Package manager console here and the default project will be auth API I will write the command add migration well before I do that let me show you something else where we have the on model creating let me comment this out for a second and then try to add a migration call that add identity tables the migration here will fail and you will see that error pretty soon perfect you can see the error enabled to create a DB context of type identity user login it requires a primary key to be defined now you do not need to go into these complexities if you want to remove that error we are not using this method we can remove that and that error goes away but if you are seeding some data right here then all you have to do is add this one line that I said before once that line is there if we try to add the migration again the migration will be added successfully perfect you can see here it is creating quite a few tables we have ASP natural rules table asp.net users table with many columns here we have the role claims table user claims table user logins and much more all of these tables are related to the.net Identity that way we do not have to worry about the heavy lifting dotnet team has provided this out of the box solution that we can use and that is pretty solid we have the migration here we can hit the command update database but I might see the error message with invariant that is there edit the project file remove this and if I run that again we will see one more error message perfect you can see the connection string property has not been initialized I want you guys to figure out what exactly we are missing if you set connection string you are spot on in the coupon API let me copy the connection string we will paste that in the auth API we forgot that database name I will change that to be auth here and let me execute update database it should work this time even if you did not run the command update database if you started the project it would automatically apply migration based on the code that we have inside program.cs but you can see the migration has been applied successfully let me switch back here refresh the database and perfect we have the mango underscore art and it has quite a few tables related to.net identity now right now in the default implementation of identity if you examine the asp.net users table you will notice it has quite a few columns it has a column for name it has a column for phone number and that's about it when it comes to user details what if you want to capture more details from the user like name of the user and street address anything else that you want how can you configure the.net identity tables and add more properties on there the way identity has been designed it is pretty extensible so let me do that we will go back to the project here and inside the auth API let me add a folder with the name of models in there I will create a new class file call that application user now we want to add more properties to the asp.net users if we examine program.cs the default user is identity user so basically we can say that application user will extend the identity user and add the using statement when we do that application user will have all the properties of identity user on top of that let's say we want to add name of the user now when we do that we have to define the change in the DP context let me close all the tabs other than this open the DB context of auth API where we have identity user this now will be application user when we were working with the coupon API we used to create a DB set so let me do that for application user and with that we have to modify the program.cs when we are adding the identity the default user now will be application user and not the identity user with that change we have added a DB set in the application DP context so you might be thinking that it might create a new table with the name of application users but it will not do that Entity framework code is smart the.net knows that application user is extending the identity user because of that it will add one more column to the asp.net users table let me show that let me add a new migration here I will say add name to asp .net users and perfect you can see here it is adding column name and it is adding that to the asp.net users table if you run the project we do not have that as the startup project in the multiple here let me select auth API as well and run the project it should automatically apply migration let me go back and perfect we have the name column right here so with that you can see adding new columns to the built-in tables of identity is not that difficult now we want to work on the auth API and we need to create endpoints in the auth API we have the default weather forecast controller let me delete that we do not want that as well as the model in the controllers folder I will create a new controller that will be an API empty controller I will call that auth controller well let me call that auth API to be consistent the route name here I do not like controller I will change that to be API forward slash auth right now what will be the two endpoints in this controller first one will be to register an account and next one will be to log in let me create HTTP post there give it a name of register and it will be a public async task of I action result call that register right now we can return okay that is fine copy the register paste that for login here and perfect we have to API endpoints that we added in our controller let me set the startup project here to be the auth API and run that perfect we see both the endpoints we have the end points for our auth API where we have register and login we need to think about what will be the dtos or models that we will need for all of the endpoints one thing that will be common when it comes to coupon API is the response dto let me copy the dto folder here from coupon API paste that in models I will delete the coupon dto we do not want that response dto we need to make sure to change the namespace to be auth API now with odd API we will be working with user application user will have many properties that are not needed when we typically work with user like if we go to database you can see application user has lockout enabled access field count concurrency stamp security stamp all of those are not needed in the details of auth API let me add a class for user dto and in there I will add the critical properties that we care about user the main four properties here will be user ID and user ID will be a grid and not an integer because of that it will be a string that is the default type for user ID in.net identity next we will have email of the user name of the user that we just added and there is also a default property for phone number then first we want to think about all the models that are needed when we register a user at that point we will require name email phone number and on top of these three we will also require password that a user wants to set for their account in the dto here let me add a class here I will name that registration request ETO and we will copy the three properties on top of that I will add password right here let me correct the spelling of registration and that looks good for the registration request similarly when we have to login we need a dto for that as well I will call that login request dto and let me correct the case here for dto and the user dto as well perfect that looks good let me go back to the login request dto when a user wants to log in they will typically send username and password so here we will have two properties first one will be username next one will be a password if a user is able to login successfully we will return a user dto of the logged in user on top of that we will have to return something called as a token that is the basic security where we return the jwd token to validate that okay you are logged in and this is your special token that will prove that you are logged in successfully in the dto let me create one more class and I will call that login response dto there we want two things first is the user dto and next one will be a string that will be token perfect with that I believe we have added all the dtos that are needed for Authentication when we work with authentication we deal with creating JWT token that is used to validate a user that is logged in you can see in the login response dto we added a string for that token now that token is generated with the help of a secret key and there are few more settings that you can configure I will add all of the settings in one place that is app settings.json here let me create a new section I will call that API settings in there we will create a section with the name of JWT options and there we want three key value name first is the secret key that we will use and you can make up your secret key I am adding a placeholder here that this is used to sign in and verify JWT token replace it with your own secret next thing is an issuer and this will basically be like who issued the certificate or this token we can hardcore that to be mango art API here and then we have something called as an audience audience will basically be that okay this token has been generated but it has been generated for certain audience and we can give that a name of mango client what that will do is if some other audience tries to pass the token it will treat that token as an invalid token now we have added these settings inside the app settings if you want to access them individually you can get the configuration object but there is other way of accessing that in your API what we can do is in the models here let me create a new class with the exact name that we have here that is jwd options and in that class we will create three properties with the name of secret issuer and audience we will set all of them by default to be string dot empty next what we can do is in program.cs when we are configuring the pipeline we can configure that JWT option all of these properties should be populated with the values from app settings for that we will say builder.services.configure and we want to configure the jwd options that will be configured by Builder dot configuration dot get section inside there we need the key name if we go back to app settings that is inside API settings we will add a colon and we have jwd options that will basically configure the class file and using dependency injection we can access the settings that we have right here now when the time is right we will access that but right now we have configured that in our container now we want to add services to our auth API an art API let me create a new folder for that to organize everything in a better way we will create service folder a new folder for I service there and we will add our first interface in there that will be I auth service think about what will be the endpoints in this interface we will have something for login and register when a user is registering what will be the return type that will be user dto let me call the method as register here and what will we receive as input parameters that will be the registration request dto let me call that the same here and that looks good now when a user is logging in the return type we have that as login response dto method name will be login and the parameter that we will receive will be login request dto then we need to implement the art service in the service folder we will add a class file auth service and it will implement the I auth service let me Implement that interface and perfect now you might be wondering that when we register a user we have to create a record in this table maybe some other tables related to Identity and the password hash that we have here we will have to Hash the password and do all the complex security that will not be the case with dotnet identity they have given us many helper methods to automatically create the user secure the password assign roles if we have to and much more to access all of those helper functions that we have with dotnet identity we will have to inject some things with dependency injection now first when we register or log in a user we will be updating our database so we will need the application DP context so read only we have the app DB context call that underscore DB and then we want to inject the helper methods first one here is a user manager if you write user manager here we have to define the T user we are not using the default user we are using application user and I will call that underscore user manager when we have to work with the roles in the user we will be using something called as a role manager that will be a read-only role manager and you can Define the default role now we will be using the default rules of the application so right here let me write identity row and role manager I have to inject all three of them with dependency injection let me do that here and we will say underscore DP underscore user manager and underscore role manager these helper methods are injected automatically and we do not have to do any other configuration with that injected now we can implement the register and login functionalities let me work on register right here when we receive the registration request dto we get few properties we need to create a new application user with these properties so application user user is equal to new and there we can assign username which will be registration request dto dot email email will also be the same and we have something called as normalized email that is basically email convert that to uppercase we have the name property assign that and we have phone number assign that as well perfect with that we have created an application user based on the information that we receive inside the registration request dto the register functionality let me add that inside the try catch block here perfect we will create a variable result and now we will be using the helper method in user manager if you write underscore user manager there is a helper method with the name of create async you can see it expects an application user we have that in the user and then if you add a comma there is an overload where it expects a password that password we have inside registration request dto dot password what that will do is it will automatically create the user it will add entry in the database if there are any errors the result will display them but all of the heavy lifting like hashing the password everything is done by the.net identity what we can do here is we can check if result dot succeeded well I forgot the await keyword here it is an asynchronous method so we will have to await that and then if result dot succeeded that means the user registration was successful if the registration was successful that means we can access application DB context and retrieve the user based on the email so we can say variable user to return is equal to underscore DB we have application users that we added as a DP set use that and we can use first where we will say U dot U goes to username is equal equal to the request ETO dot email it will retrieve the user and based on that user we can create or rather populate user dto let me do that right here once we populate that we can return the user dto perfect that looks good and if there is any exception we can return a new user dto without any detail perfect so our register functionality is looking good with our art service right now we are returning the user dto when the registration is successful but I think a better approach will be to return a string and that will be empty if the registration was successful if it failed we will return the error message you can see we have result dot succeeded here so if that was not successful we can populate that error message but if everything was successful we will return empty and the else part here we can say return result dot errors DOT first dot default because that is a list and this errors is basically the identity error that has code and description we will take description that is more meaningful for some reason if it catches an exception we will return error encountered that looks good in the art service when we register we will return a string right there with that the odd service looks good in order to consume that we will do that in the end point that we created right here we need two things first we need a response dto and then we need to inject the art service let me inject the art service and let me add the response dto in the register here we will say variable error message is equal to a weight underscore auth service dot we have the register right here when we register we have to pass the registration request dto that we will receive from body let me add that when we receive that we will pass that down here and then we will check if the error message is not null or empty that means that there is some error that was encountered underscore response dot is success we will set that to be false and we will set the message to be error message finally we will return a bad request in this case and we will return underscore response there perfect but if the error message is empty that means everything was successful we can directly return back the response with that configured let me run the API perfect we have the register endpoint here let me try that out and for dummy purpose we will use the email string at string.com keep the same name phone number and password we will see an error message because password is not strong enough but we forgot to register the odd service we have to do that right here Builder dot Services dot add scoped and I auth service implementation is inside auth service perfect let me try that once again we will change the email to this drawing at string.com and execute that perfect we see the error message password must have one alphanumeric characters now with the default.net identity they have many validations for password so let me keep something secure admin123 star that should work let me execute and great we get the message empty and success is said to be true let me switch back to the database here and if I execute this great we have created our first user in the asp.net users table that is exciting news with that we have the confirmation that our register endpoint is working as expected if you try to execute that again we get the error message username is already taken and that is perfect we have registered our first user next what we can do is using the same credentials we can implement the login functionality first we have to do that inside the art service based on the login request dto we will get the username and password we will first retrieve a user from database based on that username so application users start first our default and we will say you goes to U dot username convert that to lower is equal equal to login request dto dot username dot to lower if that username is valid then the user will be populated if a user is populated then we can check their password for that we will have a Boolean let me call that is valid and in order to check password we will be using user manager we have helper method there with the name of check password async it is an asynchronous method so make sure you await that method there we have to pass the user and their password is inside login request dto dot password we will check here if user is no or if is valid is false that means the combination is invalid in that case we can return new login response dto and inside there we can set user is now and token will also be empty but if the user was found we need to generate the JWT token before we generate the token let me populate the user dto right here and I will also have the login response dto inside there we will pass the user object and token for now we will keep that empty but we will generate the token here and once we generate that we will assign that token right here finally I will return the login response dto and I believe that looks good with that configured let me consume that in the auth API controller where we have the login and point we will say variable login response is equal to a weight underscore auth service Dot Login we need to pass the login request dto we will get that in the from body here and we need to pass that model then we can check if login response dot user is now that means the authentication was invalid I forgot the semicolon there and if that is invalid we will set the is success to be false set the message and return back a bad request but if that was successful we will set the result to be login response and return back and ok with that let me run the application and see if that works we go to login here try that invalid combination let me see perfect let me change that to be string at string.com password admin123 star foreign we get the user back here that means the login was successful now the next thing that we need to work on is when the login is successful we need to generate something very special which is a jwd token login is working as expected but now when we login in the art service we want to create a token now creating a JWT token might seem difficult if you are getting started but we have helper methods that makes everything super simple we want to generate a token for the logged in user rather than clustering everything in the art service let me create a new interface here we will call that ijwt token generator the token will be a string so that will be the return type let me call the method name as generate token and the input to generate that token will be the application user that we will pass right here let me create the implementation for that inside service folder I will create JWT token generator and that will implement the ijwt token generator Implement that interface when we generate token we will be configuring our token with secret issuer and audience for that we will require JWT option and if we examine program.cs we configured that right here and because of that inside the service here we can retrieve that in Constructor using dependency injection we want to inject the JWT option here let me do that and perfect that way the underscore JWT option will have all the key values assigned from the app settings and before we implement the generate token let me go to program.cs and I will also register that service builder.services.adscoped ijwt token generator and its implementation great now we need to generate token based on the application user we will do that by using the jwd security token Handler let me add a new variable for that and we need to extract the secret key we will say variable key is equal to we will have to encode the key so encoding ascii2.getbytes and there we need to pass the secret key that is inside JWT option we can access the secret key that we stored inside app settings now inside token what we typically have is some claim like let's say you want to store the email ID username maybe something else in the token we can store all of them in a key value Pair by something known as a claim inside token so JWT token will be comprised of multiple claims let me create variable claims is equal to new list of claim and that is inside system.security.claim when we have to add a new claim inside there we can use a string like if we want to add with the key name of name and the value we can go in application user dot name with that we have created our first claim in the token now this name is fine if you want to use that but typically there are predefined claim types that we should register that way it integrates perfectly with the.net identity and rather than adding magic string here we have that inside the jwd registered claim names dot we have email if you hover then you can see it is a constant for email and let me add that with application user dot email add a comma there copy and paste that two more times next we have something called a sub for subject and there we typically store the user ID so application user dot ID we also have a claim type with the value of name and that if you hover you can see their basic constant here and inside name if you want you can store name of the user but in the default implementation they store the username and we can convert that to string now all of them are string so that we can Skip and I believe with that we have added three claims inside the claim list that we have let me rename that perfect that looks good now we have the secret key we have the claim list Final thing that we need is a token descriptor that will describe or that will have some configuration properties for a token so we can say variable token descriptor is equal to new security token descriptor there we have to configure multiple properties like you can see we have the audience that we have in the JWT option we have the key value for audience next we have the issuer that also we have configured in JWT option Dot issuer this will be issuer and not issued at let me fix that and then all the claims that we have added in the claim list we have to add that in the token descriptor and that will go in subject so a subject is equal to new claims identity and we will pass our claim list inside there we can set the expiration and that will be take time dot now we will add 7 days finally we need signing credentials for that we will be using the secret key that we added on line 22. signing credentials is equal to new and we have to generate a new symmetric security key we will pass our key there and finally we need the algorithm the common standard is security algorithm hmac sha 256 signature that is the default standard and we will use that perfect with that we have created a token descriptor that has all the properties that we want finally we need to generate the token we will say variable token is equal to we will be using our token Handler there we have a method create token if you examine it expects a security token descriptor that we have created and configured right here so when we have to return back you can return token back or you can use the token Handler it has the method write token when you pass token inside that it will write that and it will return you the final token that is needed our generate token looks great and we have implemented all the functionality that is needed to generate a jwd token we have added the method to generate token in the jwd token generator let me consume that inside our auth service we will have to inject the ijwt token generator we already configured that in the program.cs file so let me inject here with dependency injection where we have the login here we need to generate the token we can use the jwd token generator dot generate token we need to pass the application user right there and let me save that in a variable token perfect let me add a debugging Point here and see what happens we have an error let me see where that is I forgot a comma there and let me run the application we have an error here let me see it is with the JWT token generator examine that and yes of course when we are injecting the JWT option we cannot do that like this because there is no class implementation that we have registered what we did is we configured the builder.services.configure with the options if we go back here when we are injecting we would rather get an i option and there we have to pass the jwd options when we receive the JWT options here we have to extract the value and assign that to our jwd option with that let me restart the application thank you for a fact that works here let me try to log in let me enter my username here and password and let me see we hit our breakpoint and if we examine perfect something here has been generated and it is inside our token variable copy that go back to the browser and open the website JWT dot IO if you scroll down we have the encoded remove that and paste your token on the right hand side you can examine all the details that got added you can see it is adding all the claims that we had it has the user ID it has the email we have a valid issuer and audience you can see here how easy it was to generate a token and adding claims onto our token if you want to add more claims in the future that is pretty simple as well you can directly go to the JWT token generator and add them right here right now what I will do is where we have the API endpoint and Earth service and if the token is successful when we return back we need to pass the token that got generated with that let me run the application again and try that one more time now the response should have a valid token we hit execute here and perfect we get the token right here we have configured our login and register on top of that I want to add one more endpoint when we want to assign role to any user if I go back to the SQL server and examine the auth table you can notice we have ESPN at roles table but that is empty first we need to create role in the asp.net roles table and then we have a mapping table asp.net user role where we can pass the user ID and role ID to assign some role to our user what I mean by role is let's say there is a admineral and a customer room customer can access few things as long as they are logged in but admin is the only one who is able to let's say create a coupon or delete a coupon and for that when we register a user we need to assign role to a user let me go back to the application for that and inside the interface here we will create one more method that will return a Boolean flag and I will call that assigned role we will assign a role based on email and let's say the role name so string role name whatever role name we pass here we will assign that to a user with the email address that we provide in the parameter to implement that we will go back to the auth service let me Implement that interface and if you notice in the dependency we added role manager that will provide us with the helper method to create a role in our database but before we do that we need to retrieve user based on this email so let me copy this line paste it here we will check the email let me do that and perfect that way we will retrieve any user based on the email if the user is not null then we want to proceed further before we assign rule to a user we need to make sure that that particular role is created in our database to check if a role already exists or not we will say not here underscore role manager we have a helper method rule access async now here we are checking if the rule exist or not and we need to pass the role name but in the if condition you can see it will not work because this is an asynchronous method to make that synchronous we can call get a waiter dot get result and that way we do not have to write the await keyword inside the if condition we need to create a role because that does not exist to create that on role manager we have the create async and that expects a new identity role where we need to pass the role name let me pass that role name here I added an extra bracket here and we will have to add the getawayter dot get result that will create a role if it does not exist and then we have to assign user to a particular role we can do that using user manager we have helper method there add to role async now when you are working with role remember that you can work with one role or multiple roles we want to add one role so we will use add to role async and that expects the application user and the role name we will pass both of them and finally we will return true if the user is known we can return false here and that looks good for the assigned role with that configured let me run the application and we forgot to add the end point in the auth API let me do that real quick here copy the login paste that one more time name I will call that assigned role we will assign role when a user will be registered from the front-end application so let me expect the same dto registration request dto here we have assigned role we need to pass model dot email and the role name now we do not have role name inside registration request dto let me add that here save that and we will pass model dot row convert that to an uppercase that way we do not have any casing ratios when we are creating role let me change the variable name here to assign role successful and if that is not successful we want to display error message here error encountered if everything is successful we return the response back let me run the application and see if that works let me register a new user right here and when we are registering let me give that a roll of admin now even though when we are registering we are not using that but I still added that right here perfect user is created if we go back here asp.net users great we have that now we need to assign that user a role let me copy the dto that we have here we are using the same one to assign a row paste that here we only care about email and role but if anything else is present here we will ignore that let's see what happens perfect is success is true there let me examine the asp.net roles table great admin role has been created if I examine the asp.net user roles table that role is assigned to a user that ends in number eight and if we examine that is admin gmail.com with that we are able to assign role to a user successfully now you might be thinking that hey why did we not combine the assigned role with register functionality you can do that if you want but the reason I am keeping things separate is when we will be calling the endpoints from front end we will register a user with the default role of customer and then if a user is already logged in as an admin user only then they will be able to register an admin account that complexity we will cover in the upcoming videos but right now the end points that we have in auth API are working as expected we have the art API that is functional but now we want to consume that from our web project let me close all the tabs here and we will be working on the web project first what we need to do is we need all the models in our web project as well because from there we will be sending in all the requests and getting all the response back let me scroll down to the models of auth API dto I will copy all of them other than the response dto that we already have in the web project we need to change the namespace here to be mango.web dot models let me copy that namespace I will update all the other ones here paste that login paste that perfect that looks good let me build the solution and perfect that works we also have to configure the URL for auth API I believe that is 7002 that is correct inside the web project we have utility static detail let me create an auth API base for the URL in app settings I will copy this paste that again for the auth API that will be 7002. we need to configure that in the program.cs here copy and paste that here it will be for the auth API base and service URL art API now we have configured the auth API base URL and we added all the details that are needed in our web project inside our web project we need to create the auth service similar to the coupon service let me add the interface here new item that will be I auth service and in there we want three endpoints all of them will return the response dto the first one let me call that login async when we are logging in we need to pass the login request dto copy and paste that two more times next we have the register here and we have the assigned role foreign role we will be passing the registration request dto let me do that copy that and paste it here perfect the interface looks good let me add the service here auth service and that will implement the interface let me examine the coupon service we need the base service using dependency injection let me add that here and let me go back and copy one of the post calls that we have and I will paste it right here we need to add the asynchronous keyword let me add that perfect now what will be the end point that is API forward slash auth and the base will be auth API base data that we have to pass is the registration request dto and perfect that looks good but when we have the URL along with auth this is for assigned role let me double check the name that I am using we have assigned role at that here copy this paste it two more times next one is the register we go back we have register copy that paste it here let's go back we have the login let me close that and I will pass it right here we will have the login request dto final thing that we have to do is configure our program.cs in the web project where we need to add the HTTP client for the auth service and we need to add the scoped implementation for auth service as well perfect that looks good with that if I run the application well we need to configure all the three projects everything should work exactly the same right now we are not calling the API but we have configured the art service in our web project and perfect the web project should work exactly the same next thing that we have to do is add a controller for authentication in the web project and we have to configure login and registration page now we want to build the registration controller in the web project in controllers in the web project let me create a new controller I will have to stop the application there it will be an MVC controller name of that controller will be auth controller we will be using our art service for login and registration let me inject that with dependency injection we do not want the index action here we rather want the login and log out we do not want the index action here we rather want an action method for login and there we will be passing a new login request dto when we return back to the view we can pass that and let me use the new syntax let me copy this and paste that one more time for register and with that we have the register view model or rather we can just keep that empty that is okay we have added the get endpoints for login and register with that we have added the endpoints for login and register let me go to our nav bar in view underscore layout and right there after the UL here let me create one more URL element we will have a list in there give it a class of nav item and in the first one we will have the login link let me copy the anchor tag paste it one more time it will go to the auth controller we do not have ASP area remove that action name will be login and it will be login copy that paste it one more time that will be for register let me do that perfect we want the login and register to be displayed if a user is logged in with the.net application we can directly use the Razer syntax here and check if not we have a user object that gets populated using the claims of the logged in user on there we have a property for identity and there we have a Boolean flag if the user is authenticated or not if the user is not authenticated we will display login and register in the else part if a user is already authenticated we will display them to log out we have not added this action but I will add that in the auth controller let me add that right here log out and perfect that looks good and perfect with that we have added three action methods in our auth controller let me run the application here and we should see the login and register on the nav bar we have that but the designing is off let me see where we have the UL we will give class of navbar nav and perfect that looks good if you click on any one of them we have not added the view so you will run into error message let me work on adding the views in the next video let me work on creating views for our endpoint we only have to create them for login and register let me stop the application add view empty View this will be login and we will create one for register let me do that perfect let me work on the login first the model here we will receive will be the login request dto we will add a form with the method of post inside there we will create a div with the class of container border padding for and another div with an H1 for login then let me add a div give it a class of row text Center we will be displaying all validation for that we have the ASP validation summary we want to display all the validation here and class will be text Danger after that we will add a class of row where we will have the input fields for username and password we will add a div give it a class of column 6. offset that by 3 and padding bottom often first input tag that we want will be ASP for username and give it a class of form control placeholder will be user name and I believe that looks good let me copy and paste that one more time we have the password let me paste that one more time here and for the last one we need a button type will be submit class will be form control and ptn success for the green color let me give that a value of submit here and we will display login I will also add BTN class that looks good we do not want to waste much time in the designing here let me run the application and see if that works we go back to the login perfect that looks much better perfect that is looking great I will make one small modification on the small screen I will make that column 12 but on the medium or larger we will add the offset let me copy this and paste that go back here and it stays the same that looks good let me design the register go back and copy this paste that in register and we need the model model will be registration request dtl I will change the H1 here to be register and we need email here let me add that placeholder will be email [Music] copy and paste that two more times here we have the phone number well we should get the name before that and we have phone number we have the password that looks good let me add the individual validation for all of them we can remove this div here we have email paste that name phone number and password we will have the register button here save that and let me go back perfect the view is looking good let me add some padding here padding three great with that our UI is looking great for login and register right now when we are registering a user we have not defined what is the role of a user let me add a drop down here because right now we are still configuring things but we will remove that later on I will stop the application inch direct details let me add to constant here for role admin and role customer I want to retrieve both of them and create a list of Select list item we will call that variable row list is equal to new list of Select list item we want to create the first one select list item where text is SD dot roll admin and value will also be the same copy that here we need the closing bracket paste that one more time next one will be customer let me do that perfect now we need to pass this rule list to our view we can do that by using viewpag let me create a property with the name of row list that is the key name of the view back if I go back to the register view I can access that view back right here let me copy this div paste it one more time we will add a select statement where we will have esp4 we will store that in the role property that we have for our model and the class name we will give that form select that is what we have for drop down and the list of all the items that is inside the view back let me copy the key name to avoid any spelling mistake and paste it right here within the select here we will add a default option of Select row let me run the application and see if the drop downs are populated we will go to register and perfect we have the drop down now in the next video let me work on the post action method that way when we are posting here it actually calls our API we want to work on the post action method for register let me copy this paste it one more time when we register we will be getting a registration request ETO right here let me call that obj and this will be HTTP post action method when we retrieve this object we need to invoke the odd service we will get a response dto back so that will be equal to underscore auth service dot register async and we need to pass our registration request dto at the await keyword and we will make this asynchronous method perfect that looks good the response dto that we will get here will basically create or register our user once we register the user we need to assign the role let me call that as a result here and let me create one more response dto for the assigned role we can check here if result is not now and if result that is success that means the registration was successful we can check here if obj dot roll and we can see string dot is null or empty if that is null or empty then we can assign obj dot rule is equal to SD Dot customer but if the role is populated we want to create a role whichever is selected from the drop down so here we will be using assigned rule is equal to a weight on Earth service we have assigned role async we need to pass the obj there and that will create the rule if that does not exist if it already exists then it will assign that role to the user we can add a check here if assigned rule is not null and if assigned role dot is success we want to display attempt data that registration was successful and then we want to redirect them to login so we will say return redirect to action that will be name of login let me do that perfect that looks good in the else part here if there are any error we need to populate the drop down again so let me copy this paste it here and we can redirect back to The View with the obj perfect I believe that looks good let me add a debugging point and restart the application let me go to the web project here register we have a wrong place holder here let me go back to register this will be password let me select a role of admin and hit the register button we hit our breakpoint result that is successful let me see rule should be populated as admin assigned role is also successful and if we go back perfect registration was successful let me register a customer user to see if that works we will select that role hit the register button perfect let me go to database before we move forward in the asp.net roles table I do not think we have customer so that should create a new role press F5 here it was successful if I go back to the database the new row has been created with that we can see the register functionality is working as expected with that configured the register functionality is looking good in the login we have incorrect placeholder let me correct that and perfect that looks good now let me work on the login functionality we have the register post let me copy that and I will paste it after the login get here rename that to be login and with that we will have the login request dto service will be login async and we have the response dto we do not need to assign any role there let me remove that if that is successful I want to deserialize that and we should be getting a login response dto let me remove everything else here we want the login response dto we need to use Json convert dot d serialize object that will be of the type login response dto and we will have to convert to string the result dot result and I think the name is not that good here let me modify that in just a second I will call that response dto and fix that perfect so we will deserialize and see what response we get back when we invoke login async if we do get that then we want to redirect them to the index action of the home controller but in the else part here we want to display that error message now if you notice in login we have the display summary all because of that we can add a custom error to our model State add model error we will be adding a custom error right here and the message will be inside response dto dark message if that is not valid we want to return back to The View with the obj that we receive let me remove everything else here and I believe that looks good let me save this and go back to the application let me try something invalid here perfect it is invalid let me try the valid password and great you can see it redirected me back to the home page let me try that once again and add a debugging point we go back here examine the login response and great the main thing that we care about is token and we are receiving that right here when we are logging in we receive the token we have to save that somewhere in the application because when we are accessing coupon or any other API and they request the token then we have to pass that along we can store that in multiple places like you can use a session or a cookie whatever you prefer I will be using cookies to store our token let me Implement a service for that in our web project where we have the services interface let me add a new interface and I will call that I token provider first method here will be avoid I will call that set token and we have to pass token in the parameter next one here will be get token to retrieve a token and the last one here will be to clear the token let me implement this interface in the services folder add a class of token provider and that will implement the I token provider let me Implement that interface and when we are working with the cookies we need to inject the HTTP context accessor I have already configured that in the startup class file while the program.cs not startup right here so with that we will inject the HTTP context accessor and first we need to set the token on context accessor we have the HTTP context on response dot cookies we want to append a cookie and for that we will have to give a key value pairing to store the key name let me do that in static detail let me create one more constant I will call that token cookie and we will call that JWT token when we are appending that we will say SD Dot dot token cookie and the value is inside token when we have to clear the token we can call Cookie dot delete and we need the key name finally where we have to retrieve the token let me create a string and I will create a Boolean hash token we will check our context accessor.http context and this time we will not go to response we want to request a cookie so we will say request dot cookies dot we have try cat value I will pass the token cookie right there what that will do is if it has a value it will assign that to Hash token when we return back we can say if hash token is true then we pass the token else we will pass now and here because of the null reference we will have to explicitly check is true perfect that helper functionality looks good for managing all the token but before we see that in action we have to register that in the program.cs right here we will have Builder dot Services dot add scoped we have the I token provider token provider cut that and paste it with all the services we have added token provider but where will we use the token provider that we added we will do that in the auth controller of the web application when we log in before that let me inject that using dependency injection so private read only I token provider we will get the implementation here and let me inject that if you scroll down to the login here we are getting the login response dto when we get that back we can set the token provider using token provider.sat token we will pass the login response dto dot token now with that if you run the application let me see what happens we go back to the application log in here foreign Ted back to the application let me inspect the element we will go to application scroll up here and we have the cookies let me expand that perfect you can see we have a token right here that means we are logged in but why does our application does not read that we are logged in because if we go take a look at underscore layout we need to set something that will say that this user identity is logged in how can we tell dotnet that hey our user has actually logged in and this authenticated is true how do we Define that we can do that in the auth controller actually let me create a new method here it will be a private async task let me call that sign in async let me call that sign in user and we will expect a login request dto call that as a model right here we want to call the HTTP context there we have a method sign in async and that is inside microsoft.asp.netcore.authentication it is a built-in method but that expects a claim principle we have to build that claim principle and if you examine the other Constructor that we have we can also Define the authentication scheme we are using cookie here so we can say cookie authentication defaults and there we have the authentication scheme which is basically a constant for cookies and next we need to pass the claims principle let me create that here I will call that principle is equal to new claims principle and when you do that in the parameter here you can see we have an option to pass the identity in that identity we have to add few claim types when you add a certain claim types that are registered with the.net identity then it will have the authentication checked in when we were generating the cookies you remember we had few JWT registered claim names we will have to do something similar right here let me create a new Handler here for jwd security token Handler and we will install the nougat package for that let me stop the application here after that we will need to read the JWT token so on Handler we have a method read JWT token and there we will pass the model dot token I do not see that here because it will be login response dto and not the request there we go that will basically read the token and from that token now we want to extract all the claims that we added let me create a variable identity that will be new claims identity on the authentication scheme of cookies then on identity here we want to add a claim what claim do we want to add let me open the auth API here and let me go to Services we have the token generator there we have these three claims copy that save that and let me paste it right here the first one here is the email let me move it inside the bracket here new claim that will be email and how do we get that in the JWT we have the claims and there we can use first or default we will say U goes to U DOT type is equal equal to we need the same constant let me paste that right here when we get that we will say dot value and that will extract that particular claim and add that inside our identity let me break that in a separate line here and we are missing a closing bracket that looks good now let me copy this and paste that two more times next what we want is SUV copy that add that here and we want the name claim now these are the default claims for email subject and name but when we work with.net identity we have to add two more claims so let me do that copy this and let me paste that one more time now rather than JWT register claim we also have claim types dot name if you hover on that it has the identity claim for name and there we have to pass the email so right here we will pass email and that way the claim types dot name will be populated finally where we have the principle here we will add identity and with that all the steps will complete well where we are signing in the user we need to pass the principal that will sign in the user using the.net identity these are the basic and the default steps that are needed to sign in a user using the built-in.net identity now with that configured let me go to the sign in method that we have in login right here before we set the token here we will call our sign in user and we will pass the obj well not the obj because that is a request we want the response that is login response dtl perfect that should sign in the user with that let me run the application and show you one error message let me try to log in here and when we hit the login button we will see an exception we see no sign in authentication handlers are registered try to Google the error and see if you can figure out what is going on here I hope you were able to figure out the solution we are using authentication in our web project but did we register that in our services or in the pipeline we have not done that because of that it is giving us a hint here did you forget to call the add authentication dot add cookies and we obviously forgot that we will go to the web project here program.cs and on Builder dot Services we will be calling add authentication what will be the type that is Cookie authentication defaults dot authentication scheme that is basically a constant for cookies and on there we will say add cookie and configure view options I will set few options here like from hours we will set that for 10 hours login path if a user is not logged in then it should redirect to auth controller login action and if access denied is found it will go to an action method of access denied now I have not added that page but you can add that if you want when we go to our request pipeline we also have to add app.use Authentication and that will be before authorization with that configured let me run the application let me go back try to log in here and perfect now you can see it knows that we are signed in and it is automatically displaying us the logout button so that is great but we need to set the functionality of logout let me do that real quick where do we have the log out here we will say await on HTTP context similar to sign in async we have the sign out async on top of that we will have to clear the token do not forget to do that and once we do all of that let me redirect to action that will be index action and home controller we are using a weight here so let me add a task and perfect that looks good let me go back the hard reload should kick in here and hit the logout button perfect if this does not work make sure to restart the application sometimes when you implement things with cookies and HTTP context you might have to restart the application so let me show that again we signed in here it is working when we hit log out we have login and register our application is looking good right now but let me try one thing let me try to log in using our API here try that out we will get back a token let me copy that token and we will go to jwd.io let me examine that here we have quite a few things but we do not have a rule of the logged in user that is very critical when you are working with authorization in order to add that we will first have to add that at the API level inside the auth API let me close all the tabs and open the art service here when we are assigning the role we are passing the role name but when we are generating the token in the token generator we are not passing rule of the user now right now our user only has one role but it is possible that a user can have multiple roles because of that we will add an i innumerable for rules let me continue editing and I will open the implementation where is that right here we will get an i innumerable of rules when we get that we have the claim list here so on the claim list we can add range what we want to add is rules dot select and we will use projection rule goes to new claim type and then rather than using the jwd registered claim names we will be using the dotnet type which is claim types dot role that will make sure that when in the project we are accessing rule or we are checking if user has a role it will automatically do that mapping so on claimed type of role that is the key name value will be the individual role let me add the semicolon and that looks good now when we are calling the token generator we have to pass the role that is inside our service where is that right here we need to get all the rules of the user for that we have a helper method let me call variable rules await on user manager we have a helper method cat roles async and we need to pass the application user it will retrieve us all the roles and we simply have to pass that to our token generator with that configured let me restart the application and see if that works we are in the auth API let me do I log in again execute that and copy the token let me examine that perfect you can see role of admin as added in our token and that is great now our token has a role but when we are decoding that token in the web project we need to extract that role and assign that in the web project we will do that in the auth controller right here and we want to extract one more claim let me copy this and that is of type claim types dot roll and here what will be the type that we saw it was a string with the value of row with that configured let me add a breakpoint here save that and try that out well let me restart the application to be sure because I'm changing few things in the token let me log in as admin here we hit our breakpoint let me examine the identity claims inside there and perfect you can see the claim of role has been configured now the reason I am using claim type dot role here is because with the.net integration if you have added the claim type of role then let's say in one of the controller if you add here the authorize attribute and you say role is equal to SD dot admin this is automatically taken care of because that claim is assigned when you are signing in the user inside the HTTP context DOT sign in async and because of that it is critical to add that line now let me do one more thing here let me switch back to the application and let me sign in well we will have to continue of course perfect when a user is signed in here I want to display email that is pretty simple let me go to the layout here and let me add a one more Ally element here we do not want any link here so href we can keep that as empty but rather than log out here we want to say hello and then the email if we examine the user it has identity not identities identity dot we have the name and if you examine the claims when we were populating that we added email address there with that line if we go back perfect you can see Hello admin gmail.com and that is looking great if a user is logged in we will see that if they are not we have login and register before we continue here let me add some validation on the required fields in register and login I will go back and we will have to go to models we have the login request dto and registration request dto we will add required properties there email name phone number and password are required correct that and with the login both username and password is required with that let me restart the application and see if we have the validation I do not believe I added them but let me go back and let me open the view for login and register we added the ASP validation for but we forgot to add the script so let me do that here and login as well let me add that script here and let me go back try register perfect login great you can work on designing that I am going to keep things super simple now let me try to register a same user when we try that nothing happens so basically it is going but it is not creating that let me see if I am displaying error message if the is success is false here in the else part let me display temp data of error and we will display the result Dot message in toaster of error save that here and perfect now we can see the validation if the password is secure enough let me see what happened perfect the username is already taken let me try to log in here that does not work for anything invalid we have the validation but we can move that to toaster as well if I go back to login here let me get the individual validation for username and password remove the validation summary from here and where we have the auth controller copy this and in the login paste it right here want to return back to The View with the obj leave that here and this will be response dto.message and rebuilt the application let me try log in we have the validation if something is not valid perfect we get the error message now our validations with login and registration are working as expected let me show you something odd let me close the application where we have the coupon API let me open that here we have the coupon API controller right here let me add an authorized keyword that way only authorized user can access coupon if I run the application again and try to access coupon after signing in we will see a different error message let me sign in first and now if I click on coupon you will see internal server error why do we see internal server error and not the error message with Authentication well the reason is simple when we take a look at our coupon API let me close everything else here we are working on coupon API for this video in the program.cs we have not defined that authentication will be handled by this API right here we will have to say app.use authentication and again that will be before authorization now when we are authenticating we are validating three things if you recall we have the secret we have the issuer and we have the audience we will have to validate our token using all three of them so if we go to the API project let me copy the settings here I can remove the jwd option I want to use the simple route here let me paste it and remove the JWT option directly in app settings we will have secret issuer and audience we need to add authent we will have to add authentication in program.cs where we have the Builder dot services first let me retrieve the secret that will be using Builder dot configuration dot get value we will Define the type here and then we need the section name API settings paste that here and the key name is Secret add a colon and paste that will retrieve the secret similarly we will get the issuer and the audience then if you remember the secret before encoding that by ASCII 2 so we will add that code here and finally on builder.services we will add authentication and we will configure some options there we will Define what is the authentication scheme and the default challenge scheme both of them will be better and it is a constant with the better value then we have to configure the JWT better token let me do that here and when we are validating the token what are the validation parameters so x dot token validation parameters and we have to create the object and Define what exactly we want to validate let me add the using statement here perfect and first thing we want to validate is the issuer signing key set that to be true we have to Define what is the signing key here and that will be new symmetric security key we will pass the key right here next we want to validate the issuer as well set that to be true here and we have to Define what is a valid issuer that we have in the variable similarly we will say valid audience and validate audience will be true you can Define way more parameters if you want but these basic parameters are looking good for our Authentication on top of that we also want to add authorization in our API so let me add that with that we have added authentication in our API if you run the application now you will not see the internal server error message anymore let me show that we go back here dry coupon and perfect now we see a valid error which says unauthorized before we work on accessing coupon from our web project let me go to the API project that we have coupon API and here if we try to access coupon it will not work we get a 401 not authorized how can we add authorization or authentication using swagger that we have in the API for that we have to configure the Swagger gen and add some configuration right there let me go back to the program.cs of the coupon API and we are adding the Swagger gen right here there we have to configure few option goes to and first we have to Define option dot add security definition we are using better here so we will say name is banner and we have to define the security scheme which is a new open API security scheme add the using statement in there we have to Define few things like name authorization description you can write anything you want I have added something meaningful here and what is the location for the barrier token we have written that it will be inside header and scheme is better this is the default settings so do not panic on what we are writing here think of it as something that is needed by default when you are adding authentication to your Swagger documentation finally on option you will also have to add the security requirement and that is open API security requirement object we need to configure that as well now that will expect a new open API security scheme and inside there we have to give a reference now again do not panic on why we are writing such ugly code what is all of this complexity it is one of the basic thing that is needed to enable authentication in Swagger gen documentation this will be new open API reference here and we have to Define two things type will be reference type dot security scheme and what will be the ID that will be better rather than having magic string as better here we have that right here so copy and paste that here as well as right here it will be better along with the open API security scheme we have to give a list of values we don't want anything here let me pass an empty string there with that ugly configuration that we have swaggergen is configured let me restart the application and now you will see a lock icon next to the API and perfect now how do you authorize this token if we go back whatever we wrote here it is basically adding that in the description and we have to give the better token to get that token we will have to go to the auth API and let me log in here as admin gmail.com get that token here copy that go back here when we paste it you can see I entered in the description you have to write better leave a space and then the token we will write better here paste that token and authorize perfect with that if you try to execute we see an error message where it says better error invalid token error description the audience is invalid why is that let me see let me go back and where we are validating things we have audience that looks good here let me add a debugger and rerun the application I want to see all the value and of course you can see we are getting the secret but not the issuer and audience I believe the reason behind that is first we will have to get the section and then all the values so I will say settings section is equal to Builder Dot configuration.getsection we want to get the complete section of API settings here and once we get that on the section settings we want to get the value here we will only pass the value save that and let me restart we are getting all of them here that looks good I need to validate everything again let me log in first get the token from there add that to our coupon API authorize and let me try the get here perfect so you can see if audience or anything is not valid the token is considered invalid and API does not return back the result now we want to switch back to the main application and there when we are trying to access coupon if a user is logged in we want to access all the coupon right now we get unauthorized and that is because when we are calling the API we are not passing the JWT token that we saw when we were calling the coupon API we added the better token we already have that token in the cookies if we examine we have the JWT token so when we are actually making the API call in our Base Service we have to pass that token to our API for that we have to modify the base service let me close all the tabs here open the web project we have the base service and the interface right here let me add a Boolean I will call that with better and default value will be true let me add that in the Base Service as well with better will be true and right here if with batter is enabled then we want to set our token to get the token here we have the token service which is token provider let me inject that here we will have a private read only a token provider I token provider here and perfect that looks good we can retrieve the token here using underscore tokenprovider dot get token then on the message dot headers we have to add an authorization header if you make any spelling mistake in the authorization here things will not work and when we add the better token we need the better keyword so again do not make any spelling mistake here I just did that there we go we have better and then we will leave a space at the token perfect with that configured let me run the application let me go to the web project here we will log in try to access coupon and great if you log out and try to access it displays unauthorized with that we are successfully passing the token what will happen is by default we are setting that to be true but we do not have to pass token when a user is registering or they are logging in we can go to the art service here and we can overwrite that with token with pattern will be false here copy that well when they are assigning the role let me pass that but when they are logging in let me remove that for now we save that and if we go back let me try to log in here everything should work exactly the same before I wrap up the video I want to clean something up in the coupon API let me go there minimize this coupon API program.cs you can see it is getting too clustered here this authentication code that we have here let me move that to a different file and that way the program.cs will not be too cluttered I have to create a new folder let me stop the application in coupon API we will create a folder for extensions inside there let me create a new class file with the name of web application Builder extensions and there we will basically be extending the web application Builder for that we will have public static web application Builder and let me call that add app Authentication when you are adding an extension method static keyword is required and this keyword is required before the web application Builder what we can do is program.ces let me cut everything that we selected and paste it right here we have the Builder object and on there we will add authentication once we add that if I go back I can also copy the add authorization but I will leave that outside here I will return back the Builder let me run the application and that will not work we did not call the extension method we have an error here it will be a static class that should work and we need to call that right here in order to invoke that we will say Builder dot the method name add app Authentication with that let me run the application again and see if everything is functional let me try to log in Access coupon that does not work we will log in here coupon should work so perfect that looks good now let me try something different if a user is an admin user only then they can create or delete a coupon but if it is a customer let's say for now they can access the coupon right here for that we will go back to our coupon API and coupon API controller everything is authorized but where we have the post action method right here let me add something different we are saying authorize and we want the role of admin now I know we have magic string here if you want you can create a static detail and hold that constant I will keep that as it is and we will add role of admin for put post and delete that in place let me go back log out and let me log in with the customer account that we created now if I go to coupon and try to create a new coupon perfect we see access denied so our rules are also working as expected let me go with admin here and I should be able to create a new coupon perfect that is working delete is also functional with that you can see we have all the functionalities with authentication and authorization in our API as well as the web project coupon is working as expected with our project and the API next thing that I want to work on will be more of an assignment because it will be exactly similar to what we did with coupon but that will give you Hands-On practice on how everything comes together let me close the application here go back to our service and there let me create a new project web API project I will call that mango.services.product API we will select.net 8 here let me hit the create button inside product API we will be performing thread operation on product itself and it will be exactly similar to what we did with coupon first let me create a model for that in the folder here we will have models and there we will have the product model and inside there we will have properties for our product I will create six column in the product table first one will be the product ID name of the product price we will have the range validation there then we have description category name and image URL right now when we are working with image URL we are going to use online image and not work on uploading a new image in our API we want to focus on learning microservices for now so I will keep things super simple you enter a URL inside the image URL property and that image will be displayed for that product I will create the same properties for product dto because when we are working with API we do not want to expose the core model and models here we will create a folder with the name of dtos and I will make it uniform keep that as dto and there I will add a new class that will be product dto not dtos rename that to be ddto perfect in there we will add the same six properties that we added for the product model without data annotation that looks great with that configured next what I want to do is run the coupon API edit the project file copy all the package references and I will add them in product API that way we do not have to worry about adding the new kit packages that looks good finally what I can do is copy the data folder here paste it right here and modify the namespace to be product API the DB set that we want will be product here and let me call that as products when we are working with the product here I want to see some records in the product table rather than typing all of that based on my model I have provided Snippets in the project resources and in section 6 we have seed product copy everything from there we will paste it inside the on model creating and perfect you can see we have the product ID name price description image URL is a blank image with the pixel size and that looks good with that configured I have the base setup that is needed for you to continue the assignment let me walk you through the assignment in the next video it is time to practice the API and everything that we have learned so far what I want you guys to create is set up the product API database and table we created the product model and see that the data but we have not added connection string or created that database so you need to create database populate table using the apply migration in program.cs and for that you will add the DB context and we already have the code to seed our product table with five records you will also have to set up Auto mapper in the project and perform crud functionality in the product API similar to what we did in coupon API finally you need to set up authentication and authorization in the product API where create edit and delete functionality admin role can perform those and read functionality any authorized user can perform that that is similar to what we have done with our coupon API now the five steps that I have here will be part one of the assignment once you complete the part 1 in The Next Step you have to consume the API from the web project when you consume that API the product API port number should be updated to Port 7000 and you have to implement the product service and controller in the web project finally you will have to create views for the product crud operation to be uniform with the naming here this is the naming that you have to follow we will have a view for product create product delete product edit and product index I have also provided you Snippets for the product index and product create product edit and product delete will be exactly similar to the product create so good luck with the assignment and I will show you how to do all of that step by step from the next video but before you move on to the next video I want you guys to pause the video and try this out everything that we will be doing with product API we have done in the coupon API and my main reason to have this here is for you to practice and get familiar with how the data is Flowing from web project to the API project and when you build that yourself you will run into error message that way you will get experience in solving those exception and error messages so make sure that you try to complete the assignment before you move on to the solution in the next video first thing that we will handle here is making the product API up and running and it is exactly similar to what we have in the coupon API for that we will copy few things from coupon API and modify the namespace like the extensions folder let me copy and paste that for the Authentication update the API here to be product API namespace and that looks good let me also copy everything from the program.cs in the coupon API paste that in the product API add the using statement for DB context here and we need the mapping config let me copy and paste that in the product API update the namespace here to be product API and when we are working with the product API it will be product ETO to product if you do not want to write it over you can use dot reverse map that will do the reverse mapping as well perfect program.ces add the using statement [Music] and great let me see what else is pending in the dto we need the response dto let me paste that I accidentally build let me copy again paste it here update the namespace to be product API perfect let me close that here and we need the app settings copy that paste it right here we need to update the database name to be mango underscore product then we also have to update the port number in launch settings which number do we want that is seven thousand let me update that looks good final thing that we have to do is add the controller let me copy the coupon API controller paste it here and let me remove the weather forecast we do not need that open the coupon API rename that to be product API perfect let me add the using statement for app DB context and response dto and remove the coupon API references we do not need that update the namespace to be product API the route here will be product let me fix that and basically wherever we have coupon here I need to replace that with product I will only have that file open here press Ctrl shift f we will go to replace in file I want to find Coupon replace that with product not in entire solution make sure and make sure again you select the current document only replace all looks good let me see if anything is pending here add the using statement get looks good when we are working with product we do not have get by code let me delete that perfect we have the dto product and I believe that looks great let me do a Ctrl F here and see if we have coupon we do not that looks good with that configured let me remove the authorized keyword for now and where we have the authorized by role let me remove that I want to see if everything is functional I do not want that project let me stop here set the startup project not that I want the individual so let me select and set that as a startup project and run the product API we have few errors here let me see remove that and run again we have the globalization invariant error and we will go to the project file for that we will remove this here and then we need to add migration we will go to tools package manager here default project should be product API add migration add product and Seed table it should create the product table and it should also insert data that looks good all we have to do is run the application apply migration will already be taken care of from the program.ces file let me execute here and perfect we have all the product here that looks good let me try to create a new product here and see if that works execute that and perfect success is true let me try to get all again and we have that product as well if I try to delete that let me see ID is five try that and we get the success if I try to retrieve all perfect product ID 5 got deleted so our product API is looking great and that is perfect what we can do is if I go back here inside the product controller let me bring back the authorize that we have perfect and with that we need to work on the web project to call our product API next part of the assignment is to consume our API from the web project first we have to add the service similar to the I coupon service copy and paste that here this will be i product service let me copy that name replace it where we have coupon I will have to replace that with product where we have the coupon dto it will be product dto and we have to add those details as well we will go to the product API in models we have the dto copy and paste it right here make sure and again make sure to change the namespace perfect that looks good let me replace here to be product dto and perfect interface is looking good let me copy the coupon service paste that here and rename that to be product service then inside the product service we will do Ctrl shift F replacing file we will replace coupon with the product on lowercase and we do not want in the current project only in the current document make sure to select that or else you will mess up everything else once that is done let me do the uppercase coupon with the uppercase product replace all perfect that looks good I need to create the product API page let me do that in static detail copy this paste it here and copy that name product API base then let me go to the app settings we will have to add that URL here that will be product API the port number is 7000 we will add that and configure program.cs with the new URL or the product API base that is product API we will have to add the HTTP client here for the i product service implementation is in product service we will also have to add the scoped implementation so I product service and product service that looks good for all the changes inside program.ces file let me examine the product service API product that URL is valid and this looks good let me close all the tabs here our service is looking good before we add the view or anything else let me create a controller we can copy the coupon controller paste that here rename that to be product controller let me update all of that here as well replace in file we will replace coupon with product or lowercase in the current document let me see this is not coming up here close that and let me open that once again for some reason you can see the find and replace is not working for me let me manually update that product controller we will have to go with the hard route of updating that manually call that as product service and it will be I product service copy that here product service and let me add that in dependency injection then let me copy this product service and replace that in all the places rather than coupon here it will be product copy that I will try to replace where I can I am using the capital case so let me update all of that for fact we update this it will be product dto let me replace that in all the places here perfect that looks good let me see what else we have we have the get all products async deserialize that looks good product create looks good this will be product index perfect we will display product created successfully copy that we will rename that to be product dto copy and paste that here we have product ID inside there for fact and product detail let me do Ctrl F and try to find Coupon here we have product ID replace that and we have product deleted successfully add that here and perfect we do not have any more instance product controller is also looking great let me add a debugging Point here to see if the response actually works in order to see everything in action in views we have to create the product index let me add that view here with the product index now the view here I have provided that in the snippet so let me go there we have the product index copy that paste it here we need the model here that will be I innumerable of the product dto if you scroll down here where we have the tea party we need to add for each Loop for all the item in our model close tag right here we need to display the name that is inside item dot name category name will be inside item dot category name then for the price we have item dot price convert that to a currency format where we have the pencil icon we want to add the ASP action that will be product edit and when we are editing we want to pass the product ID so we will say product ID is equal to and that is inside item dot product ID perfect then we have the delete here the action for that will be product delete ASP route we will pass the product ID again and that will be item dot product ID that looks good final change that I want to do is inside underscore layout we need to add one more link here content management copy the Ally element here paste that one more time for product it will be product index action and perfect I believe everything looks good with that configure the startup project and we will start all the project let me see what we have accomplished so far let me log in here as an admin and we click on product we go to product index press F10 response perfect we got the response back let me go back to the view and great our product list is coming up and that is great news in the next video let me work on the remaining functionalities we are able to display all the product if we log out here and try product you will notice that will not work we get the unauthorized so our authorization is also functional here let me log in back here and we want to perform the other crud operations on product now I have provided the product create here you can copy that or you can use create from coupon here and modify the property names let me do that with the coupon I believe that might be simpler where we have the views let me first create all the views add View we want the product create go back here copy product delete add View and then in the product controller similar to product Elite we will be adding the edit functionality as well let me copy the product edit paste that here rename that to be product edit here when we edit we will receive the product ID and I believe this looks good for the edit as well but when we are editing we want to call the update product async and we will pass the Complete product dto that is successful we will say product updated successfully else we have the error message let me copy the name here add View add product edit View finally we want to create all the views here let me copy the coupon create view here copy that paste that inside which is this one let me see it is product delete we want product create paste that here and this will be on the product dto action will be product create let me copy the product here create product there we will have name of the product add that here then we have the category name copy and paste that here after that we have the description copy and paste that scroll down let me copy and paste this two more times we have the image URL and we have the price believe yep price let me do that right here perfect that looks good this will be product index and great that looks good copy the product create paste that for product edit update that to be edit product everything else will remain the same yep that looks good here it will be product edit and we have the product delete let me paste that here when we are deleting everything will be disabled let me add that and we will remove the validation we do not need them one thing that I forgot is for description this will be a text area we need the closing tag here and we will add rows let's say five row let me copy this paste that for the other description remove the disabled and perfect let me save this and run the application now I am going super quick with the product here because we have already done that for our coupon let me go and when I create a product nothing happens let me see what link I have in the product index I forgot the ASP action that will be product create change that and perfect let me try to create a product here that works let me try to edit that when we try to edit you can see it is rather creating a new product so something is not valid there we will go back to the product and the reason behind that is we do not have the hidden property or the ID let me try that let me add the product ID as the hidden property here and try that once again we will change that to be two that works so that was the root cause because we did not have the hidden property when we were posting the form it was setting the product ID to be zero because of that Entity framework created a new record let me see delete here and in delete we forgot to change let me go back this is create let me open delete here and it will be product delete product and BTN let me change that to be Danger value will be delete perfect save that let me hit delete and we get the error it does not delete the record let me see why that is in the product controller let me close all the tab here it gets confusing super quick where we have the delete HTTP post add the debugging point and try that it hits my breakpoint here and I do not have the product ID that is why it was failing let me open the view again product delete and similar to product edit we will require the hidden property save that let me continue here go back try to delete that we should have the ID that looks good and perfect product has been deleted successfully with that all the crud operation are working as expected if we log in as a customer here you will notice we will not be able to create a product perfect access denied so all of our validations and product API is working as expected we have about three services and we are consuming them in our web project what I want to do next is on the home page let me display all the products and for that we will have to modify the home controller let me close all the tabs here I will open the home controller and product controller in product index we are getting all the products that is exactly what we want in our home controller index view right here we need to inject the product service let me go to the product controller and copy this paste it right here we do not need the logger and modify the controller name action here we will have to make that async task of I action result with that we should be able to retrieve all the product here let me run the application and see if that works if I examine the list here we have zero something is not right here let me continue and of course we have unauthorized for now what I will do is when we go to product controller well we will have to go to API controller here remove the authorize tag we want get to be accessible post put and delete we have authorized with the admin role that looks good let me go back to the application and refresh the page our preload will kick in but I forgot to add the debugging Point here let me do that again and now we have list with the four product that looks great our controller action method is looking good let me add the index View it will be an empty View and actually I think we already have that view let me right click go to the view we have the home page here let me Design This in the next video we want to display all the product on the home page of the application rather than typing the HTML and CSS insert the Snippets folder we are in section 7 we have the home page UI copy the HTML and CSS paste it right here let me create a model here if we go to home controller we are passing a list of product dto you can have a list here or an i innumerable for the product TTR with that with that configured let me run the application and see what is the default UI that we added perfect if you examine the landing page here we have one product we will have to add for each Loop and modify that now here I have column four let me make that column 12 if it is medium let me make it column md6 or large we will give it four you can see that looks much better now let me add a for each Loop here and we will iterate through our product I will add the for each right here for each variable product in model the M will be Capital here and let me close that right here we need to display name here that will be product dot name and then we have the product image that will be inside product dot image URL we have the price here I will convert product.price to the currency format category name will be inside product dot category name and description will have some HTML content so right here let me say HTML dot Raw and I will pass product.description where we have the details here we need to add ASP action let me call that details action and when we click on the details button we need the product ID that will be inside ASP route let me call that product ID is equal to that will be inside product dot product ID I believe that looks good let me align all of that and perfect let's go back to the home page here perfect we have all the products that are being displayed right here our home page is looking great with all the products now on the details page we want to display individual product if I go back to the controller here rather than retrieving all the products now I only want to retrieve certain product let me copy this paste it one more time here and that will be Details page inside here we are passing the product ID that name must match what we have in the ASP route that is product ID and perfect that looks good based on that we do not want to retrieve all the product we want to get product by ID and pass the product ID here the result that we will get back will not be a list that will be a single product dto perfect and this we will modify to be a product dto call that as model copy and paste that here and perfect that looks good for the details action method on top of that I want to add the authorized keyword here that way only if a user is logged in only then they will be able to view the details page the action method for details is looking perfect but rather than details here let me rename that to be product details copy that name add that view select the empty View and paste that name add that we will also have to modify in index here where we have the details the action name is product details now for the UI of the product details I will go back to the snippet and there we have details.ui let me copy everything paste it here scroll to the top here we need to define the model that will be product dto before we do anything here let me run the application and see the UI perfect let me log in here we have the authorized keyword there and let me go to details perfect let me replace everything with the dynamic content from the product dto name here will be model dot name next we have the price and for that we will convert to currency format scroll down we have the image URL let me replace that we have model dot image URL for that for category name in the template itself I had model dot category name so we can leave that as it is where we have the description we will have to convert that html.raw and we will display model dot description that looks good back to list here we will go back to the index action let me Define that here and let me save everything go back to the project perfect we have the text price description appetizer back to list is also functional and image is also being displayed on the details page we have an input field there we want to populate the number of product that we want to add to the shopping cart but if we examine the product ETO that we have we do not have anything to store that count if you want you can add that to the product ETO because we are not adding that to the actual model in the database this is only dto for the web project right here let me create a variable with the name of count and set the default value to B1 going back to the view here scroll down we have the input field we can add ASP for that is for count whoops that will be count here perfect and then we should add validation if I go back here I can use the range data annotation to make sure that it is 1 200. insert the view we will add the span with validation and at the end here we will have to add a section for script include the validation scripts partial let me save everything here and we will have to restart the application let me try to go to details here we will have to login and then when we are logging in we can always redirect them back to the original URL but perfect the count here is looking great when we hit the add to cart button we want to add the product to shopping cart now shopping cart can be of two times one you can store a local session where you can hold the shopping cart and the other route is to store a shopping cart in the database the advantages of storing shopping cart in the database is based on what a user has in the shopping cart we can send them promotional email and have many more functionalities you might have seen when you are shopping and you leave something in the cart couple of days down the road you will get a notification in your email with something like you forgot to check out and we can add all of those promotional logic as long as we are storing the shopping cart in the database and for that we will have to create a new API for our shopping cart let me do that from the next video we need to create a new project for shopping cart API in the services I will add a new project that will be asp.net core web API project call that to be mango dot Services dot shopping cart API default configuration looks good here let me create the project before I continue here let me copy the project file from product API copy the packages paste them in the shopping cart API that way we do not have to spend time in adding the nougat packages perfect so our new API project has been added to work with shopping cart before we configure the DB context we need to create the tables to maintain shopping cart now when it comes to shopping cart there are two things or rather two tables that we have to configure first will be a shopping cart header and next will be a shopping cart details header table will contain information like what is the user ID what is the coupon code what is the card total and if any coupon code is applied what is the discount the details on the other page will contain list of all the products that are added for that user in the shopping cart and what is the count of that product in the project here let me create a new folder for models and I will create two class file we will have the card header and we will have the card details it looks good let me add that and first let me work on the card header we need the primary key of the table and that will be integer card header ID for one user there will always be only one record inside the card header ID and for that we will also store the user ID that way we know it is unique then a user might apply coupon on the shopping cart let me store the coupon code here and if a coupon code is applied we will also have some discount we need to store the grand total let me do that here car total now discount and card total we do not want to store them in the database we only want them for display purpose like when we are retrieving a shopping cart we will dynamically calculate them based on the shopping cart and card detail so right now let me not add both of these fields to the database I will add the not mapped for both of them after that we need the card detail here and there we will have a primary key that will be card details ID it will be a primary key let me add the data annotation and we need the foreign key here for cart header ID I will add the navigation property there for card header now inside shopping cart detail we need to know what is the product ID store that here and then we will have to populate the product details somehow by calling the product API I will do prop here we need to add product dto if you do control dot here it will tempt you to add reference to the project but do not do that all of the micro Services project will be isolated so rather we will copy the product model product dto and let me close this here paste that in the models folder rename the namespace here to be shopping cart API perfect and that will be inside dto folder let me create that and move the product dto let me see the namespace that looks good now we can press Ctrl dot here and add the using statement that will be inside the same project product dto property let me call that as product and I will add not mapped we do not want to add that to our database we have product we have card header and finally we want count of the product right here we will have count that way we will track how many quantity a user wants for a certain product in our card detail and with that the header and detail are looking great based on the model here we will also have to add dto because when we are working with API we will not expose the root model we will only expose dto let me add a new class here for cart details dto end card header dto let me copy the property from cart header here paste them in the card header dto we do not need the not mapped there or the data annotation go to the card detail here copy this I have a spelling mistake it will be dto rename that we will remove the data annotation card header will be card header dto which can be null here product ID product ETO let me add the null as well and we have the count we have added a few DDOS right here but I will add one more detail that will basically have the shopping cart let me call that card dto and inside there we will have one card header and a list of card details basically when we want to retrieve a shopping cart for a user that will have one card header and it can have multiple card details that will be the dto that we will pass when we are working with the complete shopping cart and finally if you examine the card header we are also working with coupon code let me get the dto coupon dto and I will also copy the response dto that will be generic for all the API paste them here modify the namespace here to be shopping cart API and we will modify the coupon as well perfect with that I believe we have added all the details that will be needed for shopping cart but if some new requirement comes in we can always come back here and modify the details let me save everything and close all the tabs here now let me do the default configuration that we do for all the apis remove the weather forecast that is not needed let me open product API here for reference I will copy the program.cs paste it for the shopping cart here save all of that copy the data and extension folder paste them here modify the namespace for both the files it will be shopping cart API copy that FTP context shopping cart API DB set will be card header and card details let me create those tables copy and paste that again for card detail perfect we do not need anything on the override for shopping cart I can remove this method if I want as well that looks good let me go to the extension here authentication looks good save that then let me copy the mapping config paste it inside shopping cart here modify the namespace to be shopping cart API rather than product here I will add the card header and card details mapping config looks good let me close that actually let me edit that I need to remove this globalization or else I will get the error later on then let me copy the app settings with the connection string as well as API settings paste that here database name will be mango underscore shopping cart that looks good and with that I believe the basic configuration is done for the shopping cart API let me go to program.cs and add the using statement remove the product API from there perfect looks good let me add the using statement again and great last thing that we have to do is add a migration package manager console here default project shopping cart add migration add shopping cart tables perfect we are adding the card header and card details let me run the project shopping cart API and that will apply the migrations automatically perfect the project is running here let me go to SQL Server where we have mango we have the mango shopping cart database perfect we have the card headers and the card details and great both the tables are looking good and we can continue from the next video we need to work on creating the controller or endpoints in the shopping cart API let me create a controller for that make sure to select the API controller here and I will call that shopping cart API controller we need to update the route here let me call that API forward slash card we have the API controller now think about what will be all the services that we will require to inject here right now we will require Auto mapper because we were working with dto and then when we have to add items to the shopping cart database we will require a DP context our API will also return the response dto so let me add that as well but rather than shopping cart API let me call that card API that should be sufficient with that change let me add the response dto Auto mapper and FTP context using dependency injection we want to work on the main action method I will call that absurd because no matter if we are adding a new item to the shopping cart or we are updating existing item we will take care of all of that in one single endpoint the model that we will receive here is a car tto let me add that we will make that an async method and the response that we will return back here will be response dto perfect that looks good I can remove the I action result or and perfect that looks good for the end point and the upsert action method we will make that HTTP post because we need to retrieve the car tto from body I can rename the action method or the end point to be caught absurd and that looks good we need to work on one end point that will be responsible for creating new shopping cart entities or updating any of the existing shopping cart entries let me walk you through the logic that I want in this action method initial example will be when a user adds an item for the first time in the shopping cart right now they do not have any items in the shopping cart and they add one item at that point there will not be an entry inside the card header or the card detail we will first have to create an entry insert card header and then we will have to create the card details for the item that user is adding to the shopping cart next scenario will be if a user adds a new item to the shopping cart but they already have some other items that are added to the shopping cart in that case there will be an entry in the card header table we need to find that entry retrieve the header ID and using that header ID we have to create a new entry in the card detail final scenario will be if a user updates quantity of an existing item in the shopping cart in that case we have to find out the card details and we have to update count in card details we will have to implement all three of these functionality in the cart upsert endpoint let me do that in a try catch block that way if we get any exception we can set the response Dot message is equal to exception Dot message dot to string and underscore response dot is Success will be false now initially what we have to do is we need to find if an entry exist in the card header for that user ID in the drive block we will access underscore DB dot cardheaders dot first dot default async and we will retrieve that based on the user ID so if user ID is equal equal to cart header dot user ID then we retrieve that card header if that is now that means we have to create the card header and details but if that is not now that means that there is an entry in card header for that user then we have to check if the card details has the same product or not let me add that check first we will say variable card details from DB is equal to a weight underscore DP Dot card details Dot we have the first our default async and we will check based on the product ID is equal equal to cart tto Dot card details DOT first dot product ID now the reason I am using first here is because card detail will only have one entry because the only way to add an item to shopping cart is from The Details page of a product so it will not be possible that they will add two products at the same time so we can check the product ID here and on top of that we need to make sure that that entry is only for the user that we are working with because it is possible that a different card header ID might have the same product in their shopping cart we do not want to retrieve that so I can say U Dot card header ID is equal equal to cart header from DB Dot card header ID that way we will find out if the same user has that same product in the shopping cart or not if they do not have that so if card details from DB is now that means that we have to create a new entry part card details but in the else here they already have that product in the shopping cart so we have to update count in card details the if else logic that we have here covers everything that we have discussed in the PowerPoint right here so that way we have the skeleton laid out now we need to work on creating or updating our tables let me work on one thing at a time here first one that we have we need to create the header and detail we need to convert from dto to the model object I can say cart header here and let me call that card header is equal to underscore mapper.map and we will map the card header dto Dot card header once we do that we will say underscore DB dot cardheaders dot add that to the database here and we need to save the changes now the reason I am saving changes here is because I want to retrieve the header ID and that header ID I want to populate to the card detail so card dto Dot card details DOT first and I will populate the card header ID that will be cardheader Dot card header ID header ID will be populated here because we are saving changes on this object now that we have the card detail we can save that to the database underscore DB Dot card details dot add again we have to use the mapper here to convert that to cart detail entity got detail here and we will pass the card tto Dot card details start first after we add that we can say await underscore DB dot save changes asynchronous I can use the async method here as well let me do that perfect that looks good but the initial scenario that we have we have the initials and audio that is covered here where we have to create the card header and cart detail if we scroll down here we need to create card details when a card header already exists and if they are adding a new product to the shopping cart for that I can copy the lines here and let me paste them we need to populate the card header ID and that is inside card header from DB Dot card header ID once we populate the card detail we can add that to the database and save changes in the final section here we have to update the count we can say car dto.car details DOT first dot count plus equal to cart details from DB dot count on top of that we can also assign the cart details ID and the card header ID perfect that looks good finally rather than add we will be using update but I can copy and paste that I will rename add to be update that looks good we will await underscore DB dot save changes after all of that here we will say underscore response dot result that is equal to the new card dto that looks good we have error and we are not returning after we catch the exception we will return the response back perfect that looks good for the card upsert method but before we do anything we need to validate if this is functional we have the startup project as the shopping cart API let me run that and see if that works you will see something weird but let me walk you through all of that here we have card header we have card details and we have the product details as well we do not care about the product details let me remove all of that then in card details we have cart header that is also not needed the model that we care about is right here if you want to modify the dto to be like this you can do that but I'm going to keep things as it is for now let me paste the model here that way we can reuse user ID let me add something temporary right now it is a fake user ID that is okay coupon code I will empty that card total let me change that to be 100. card details ID will be zero card header ID will be zero we are adding product ID3 and count of 33. let me execute that we scroll down and perfect it is successful let me go to the database here if I execute that we have the card header ID user ID let me copy the details here as well and perfect count is 33 product ID is 3. if I go back here and let's say I want to modify the same card header ID of 1 car total we don't care about that but when we are modifying that let me say product ID 3 I want to add three more count execute that here and we will see an exception perfect you can see the instance of entity type card details cannot be tracked because another instance with the same value of card details ID is already being tracked this is a typical error message that you encounter with Entity framework core when you are updating an entity that is already being tracked by some other request and what I mean by that is if we go up here we are retrieving the card header and we are retrieving the card details when we retrieve a particular card details it is already tracking this card details from DB but then what we do is when we are updating few things here we are updating the car tto and we are passing that right here Entity framework code will get confused because that same ID it is already tracking right here that is why we see that exception to solve that error message when we are retrieving the shopping cart here we do not want to update the card details from DB directly we are updating the car tto and not the object that we retrieve here and because of that we can tell Entity framework that the object that we are retrieving here I do not want you to track that and we will set it as no tracking that will make sure that the object is not tracked here and we will not see the error with multiple tracking we can also add the same as no tracking when we are retrieving the card header right here with that configured let me restart the application we will try to post here and let me copy our model paste that here header ID is one user ID let me go and copy that paste it here we don't care about the code header ID is one product ID3 we want to update the count by three right now we have 33 if I execute it here we get a weird exception let me see what that is add a debugging Point here execute and let me see it is retrieving the card details from DB that looks good let me examine the card detail here that is also looking good save changes when we save the change we have an issue with the header ID did I type that incorrectly let me see the card header ID should be one how come it is three let me execute and debug that once again let me make sure that is one and let me see the dto for some reason it is passing the cart header ID as to and that is my mistake I added that you can see it should be one let me replace and try to execute that and see what happens verify the card details here and it is two whoops I just noticed here it should be equal to n not plus equal to plus equal to will only apply for the count with that configured let me try that once again copy and paste it here got header ID will be one product three count three and let me get the user ID from database perfect let me execute here it should work now perfect it is successful let me go to the database here and the count should now be 36. and that is perfect if I go back to the API and if I modify the count to be let's say -3 it will be back to 33. let me go to database perfect now let me try to add a new product for this user product ID let me change that to B2 I want five count add that here and create it adds another entry in the car details now if I modify the user ID here and we will not pass any card header ID execute that let me see what happens perfect it adds for the card header ID to the product 2 and count of five with that we have covered all the scenario to add items to the shopping cart before I wrap up let me go back and even if I added a card header ID of let's say one here and if we execute that if you scroll down here you will notice here that it was successful but we had an invalid card header ID because that user ID is actually called header id2 in that case let me do select top thousand here let me get the header as well here and perfect you can see it actually went by the user ID and not the card header ID based on the user ID it updated the count here to be 10. that logic is good for now if for some reason based on your business requirement you want to add more validation you are more than welcome to modify the API that we are building but what we have is working as expected based on my requirements now I want to add another endpoint to our API to remove any car detail let me go back to visual studio here and I can copy the Absurd paste that one more time and let me remove everything that we have right here perfect modify the action name here to be removed card and when we are removing we will be receiving an integer that will be the card details ID and we will get that from body I will be explicit about that we do not want to get that from the URL method name here will be remove cart and for that we will retrieve the card details from the database next I want to check total count of card items because we are removing a cart items from the detail and if that is the only item in the shopping cart for that user then we can remove the card header as well I will check underscore DB Dot card details dot where you goes to you Dot card header ID is equal equal to cart details Dot card header ID foreign once we get that we need to retrieve the count from there and then we can check if total count is 1 that means that it is the last item that user is removing from the shopping cart in that case rather than removing the card details we can retrieve the card header from the database and underscore TB Dot card headers dot remove we can remove the card header but before we remove that right here I can go to card detail and I can remove the card details perfect so we will remove card details and if that was the last item then we will remove the card header as well we will say a weight underscore DB dot save changes asynchronous and the result here we can set that to be a Boolean flag as true that looks good for the remove functionality let me see that in action I will go to the database let me open that up and this card detail is the only record for the user that we have so if I remove cart detail ID3 it should remove the detail and header let me see that we have remove card I will pass three there that is done here let me execute perfect it removed the card detail as well as the card header now we want to work on the final endpoint in the shopping cart API that is to retrieve shopping cart for a user we will go back to the project here and let me copy one of the method well rather than copying let me create that from scratch that will be the first one here paste the definition and what will be the name that will be cat card and there we will be passing user ID it will not be an HTTP post that will be a get action method call that as get card here we will pass the user ID that is a grid I will add the try catch block there in exception we will set the success to be false and return back the response at the end right here we want to retrieve a card dto let me call that as card is equal to new and first we want to populate the card header cart header when we retrieve that from database we need to convert that to card header dto that should be the return type now we need to retrieve that from database so underscore DB dot cardheaders dot first you goes to U dot user ID is equal equal to the user ID that will retrieve the card header and then we can populate card details again we will have to map that but it will be an i enumerable of the card details dto we need to retrieve that from database underscore DP Dot card details dot where U goes to U Dot card header ID is equal equal to cart Dot card header dot the card header ID let me break that down in different line that way it is easier to read perfect with that we are retrieving the shopping cart but in shopping cart header we have a property that is card total we can populate that with a for each Loop I will say for each variable item incart Dot card details we want to populate the card total by multiplying the count by price and then adding that for all the products finally we will return response dot result is equal to the card that we populated that looks good let me save this and go back to the endpoint hot reload does not kick in let me restart the application perfect let me go back to the database and retrieve the user ID here try that out and of course we will get the exception object reference not set to instance of an object because product is not populated we do not even have product in the same API somehow from the shopping cart API we need to call the product API to load the product details for the product in our shopping cart let me do that from the next video we have been working with apis for a while but now is the first time when we will see how microservices communicate with each other the scenario that we want to discuss right now is when we are loading the shopping cart we need to retrieve product details for that we need to work on the link or the connection that you see on the screen where our shopping cart will be interacting with the product API and for that we will have to set up HTTP client request in our shopping cart that way we are able to make HTTP calls to our product API now we need to retrieve all the product in our shopping cart API let me go back to the project here and where we have the shopping cart API we will be adding a folder for service in that folder let me create one more folder for I service whoops there we go and the interface let me add that new item I will call that I product service and that will be responsible to load all the product from the product API it will return an innumerable of product ETO let me add that using statement before I start consuming or writing the service we need to add the URL of the product API inside the app settings I will create a new section service URLs and we will add the product API that is localhost 7000 let me double check that from the web project yep that looks good with that configured now we need to add an HTTP client for this particular URL we have seen how to use the client Factory let me show you the other way around here in program.cs we will say Builder dot Services dot add HTTP client in there I will give it a name of product and we need to define the URL we will set that by ucos to U dot Base address is equal to new URI we need to create that and the URL is inside Builder dot configuration we need the key name let me go back service URLs add a colon there and it is product API let me paste that will add an HTTP client for product with the base URL right here and when we have the HTTP client set here we can Implement our service call that product service that will implement the iproduct service interface and let me Implement that interface in order to make the HTTP call we will inject the ihttp client Factory let me see how this service is different from what we have in the web project we have the product service there we were using the base service and we were directly using the send async if I open Base Service you can notice we were creating a client with one particular name we have already defined that as product so let me close the web project here and right here we will create a client that will be underscore httpcoinfactory.create client but the name here will be product based on the name here it will examine in program.cs and it will get the Base address and if I go back here on client I can call the method get async and I can provide the route right here I need to add the async keyword and perfect we will get the response back once we get the response we will retrieve the API content from there and then finally I will get the response back by deserializing Json convert we will have to add the nuget package for that dot deserialize object the response type will always be response dto via uniform and we will pass the API content finally if the response is successful in that case we will deserialize that again to an i innumerable of product dto so we will return Json convert dot we have the D serialize object I will deserialize that when I enumerable of product dto and before we deserialize that we have to convert to string let me do that the response dot result that looks good but if the response was not successful we can return a new list of product dto with that the end point is looking good but in program.ces we have to configure our service right here I will add builder.services.adscoped i product service implementation is inside product service and finally in our cart API controller right here we need to inject the product service let me do that here I product service and inject that after we retrieve the card details here let me load all the product in product ETL by calling the product service when we are iterating through the card detail I can also populate item.product is equal to product dtos DOT first dot default you goes to you dot product ID is equal equal to item dot product ID now the product ID has to be valid when we were adding things in the table here I used the product ID of 2 and 3. if this was some other ID like 10 it will not work because in the table here you can see products we have the ID 124 that we seated because of that what we have right now will work with that configured let me run the application well it will not work again because we are only running the shopping cart API let me run all the project configure startup project here and multiple startup project let me start that and let me see when I run the application I see an exception Port 7001 is in use I might have accidentally configured two API to u7001 that is supposed to be used for coupon so let me go back to the application and which one is this it is coupon API that is good let me stop here configure the startup project and let me examine the shopping cart API what I have for that whoops I used 7001 let me go back to the document that should be seven thousand three perfect let me run it again and see what happens we see the error again with seven thousand one I thought I fixed that here let me save that clean the solution and try that once again and perfect it works this time let me open the shopping cart API I will try the get we will go to our database copy the user ID paste it here and let me see great you can see it retrieves the header we have the total based on the product and count and it also retrieves the product as well that is looking much better with that the get endpoint is working as expected but now we are able to go to the product API but now we are able to call product API from the shopping cart API in our card API controller inside the shopping cart project we want to add two more endpoints where we have the card observed let me paste one more endpoint that is apply coupon right here I am not doing anything I am expecting a car tto from body and the method name is apply coupon we have a basic try catch block when a user clicks the apply coupon we want to retrieve the card from database so card from DB underscore TP dot cardheaders dot first and there we will say U goes to U dot user ID is equal equal to cart dto dot cardheader dot user ID I will update the card from DP dot coupon code is equal to car tto dot cardheader start coupon code and underscore DP Dot card headers dot update we will pass the card from DB and finally underscore DB dot save changes we are in the async method we can use the async methods here and we can do the same here as well if you want we will update that and in the response here we will say result is equal to true that is apply coupon copy that paste it one more time or remove coupon when we have to remove the coupon we will empty the coupon code and perfect that looks good with that configured let me run the application and see if that works when we are retrieving the card we are using the user ID that you can see here so let me switch back to the database here copy the user ID open the shopping cart API and apply coupon try that out I do not need anything with the card details so let me remove card header altogether the product here we don't care the only thing user ID coupon code let me say turn off if I execute that perfect it is successful let me go to database here and we have done off let me try to remove the coupon copy the body here go to remove coupon write that out and we will remove that let me see that perfect now of course you can integrate the apply and remove coupon in the same logic by passing an empty string if you want but I'm keeping things different for now with that configured let me continue from the next video as I mentioned before that we can integrate the apply and remove coupon in the same logic let me delete the remove coupon and I will only keep apply coupon when a user is removing a coupon we will pass the same car tto but we will pass an empty coupon ID that way it will automatically clear that but now we have one more thing when we are getting the shopping cart here we are populating the product here at the same point if the coupon code is available I want to go to the coupon API get that coupon code retrieve what is the discount that they should receive and apply that and modify the card total right here for that we have to implement coupon service let me scroll down where we have the product service copy and paste that here and I will rename that to be I coupon service let me modify the class name and what will be the return type we will only retrieve one coupon so the return type will be coupon DTR and we will say get coupon we will pass the coupon code let me implement the I coupon service inside service folder add a new class that will be coupon service and it will implement the I coupon service we will have to use the ihddp client Factory let me paste that and I will copy the product service let me copy all of that paste it inside the coupon service perfect this time we will be creating a client with the name of coupon and I will configure that in the startup project in just a minute but where we have the get async we want to call the API forward slash coupon let me go to coupon API we have the API forward slash coupon and then we have the get by code copy that paste it here and then we will pass the coupon code let me add the async keyword here perfect we read that back DC realize that as a response dto and we will deserialize that again in a coupon dto perfect the else part here we will return a new coupon dto power factor coupon service is looking good here let me edit the project file here well I want to go to the launch settings.json file and the port number is 7001 let me add that inside the shopping cart app settings I will add Coupon API copy and paste the path that will be 7001. lastly I have to modify the program.cs inject the coupon service and we have to register the HTTP client with the Base address name here is coupon that is what we have used and this will be coupon API with that we have configured or added the coupon API we can close everything here let me open the cart API controller and I will inject the coupon service for a fact after we have retrieved the card details here we will add the logic to apply coupon if any we will have to check here I will add a not sign string dot is no or empty F cart Dot card header dot coupon code is not null or empty then we can try to retrieve that coupon from the coupon service coupon dto coupon is equal to a weight on the coupon service we have cat coupon we will pass cart.header DOT coupon code that will retrieve the coupon we can check here if coupon is not now and we need to make sure that the car total is greater than minimum amount for a coupon so cart dot cardheader dot total that we have must be greater than coupon dot minimum amount if that is valid then we will subtract the card total minus equal to coupon dot discount amount and I will also populate card dot cart header dot discount is equal to coupon dot discount amount with that I believe everything looks good let me run all the project here and see that in action let me go to SQL server and let me examine the coupon table that we have we have two coupons 10 off and 20 off let me go to shopping cart API we need the user ID here let me go back and where is that we have the user ID and there we do not have any coupon so first we need to apply a coupon let me try that out we only need the user ID here we don't care about anything else well the coupon code we will make that 20 off here remove the card header product execute that is good let me go back to the database and perfect the coupon code is applied let me try the get shopping cart I need the user ID for that copy the user ID and let me see okay we have an error in the get coupon and we have unauthorized we have the unauthorized here let me continue and for now let me add a manual hack in the coupon API remove the authorized keyword and run that one more time now again this is temporary we will fix that very soon let me try the get here enter the user ID and perfect we have the card total here you can see discount is also populated that means that the shopping cart is retrieving that coupon it knows it has to give 10 dollars of discount and then the order total is 412.62 if I go to my database and let me try one thing here where we have the shopping cart card header edit that and let me give that a different coupon code of 10 off if I go back to the API endpoint the total was 412 dollars but now with 10 off it should only give 10 of discount so it should be 422 dollars and perfect that is exactly what we see with that we can see our shopping cart can consume both the product Services as well as coupon service with that our shopping cart service is consuming both the product API as well as the coupon API now we are on the fun part we want to consume our new service for shopping cart in the web project we have to add that URL if I go back to the presentation shopping cart is 7003 let me double check to make sure that I modified the launch settings yes that is 7003 let me copy that and here I will add one more that is sharpening cart API and I will add the URL there perfect then we need the utility folder static detail let me add that constant here that will be shopping cart API base configure that in program.cs copy and paste it we have the shopping cart API base and shopping cart API then let me add the service in the services here let me copy the I coupon service paste that I will rename that to be card service and let me also copy the implementation paste that here that will be card service let me work on the interface here and let me copy the name paste it here perfect what will be all the methods that we want here first one will be to get card based on the user ID and there we will pass the user ID then we want to add something to the shopping cart we have the observed method I will call that absurd card async and there we have to pass the cart dto now we do not have that dto in the web project let me add that I will go to the shopping cart models copy the car tto paste that in the models of the web project I also have to add the other detail let me do that we have card details and card header paste both of them here and let me modify the namespace mango.web dot models copy that modify all the namespace here and perfect that looks good we do not have any errors let me close all the details that we have open and let me work on the dto perfect absurd looks good then we have the method to remove anything from the shopping cart I will call that remove from cart async for that we are only passing the card details ID let me add that and finally we have the logic to apply coupon that will be task of response dto I will call that apply coupon async and there also we are passing the car tto I believe four of them looks good for now let me go to implementation of the card service let me copy the name here modify the class name perfect that looks good let me Implement that interface we have the apply coupon let me cut this here paste that that will be a post that is fine make that async data we will pass the car tto and then we need the URL that is API forward slash cart and let me double check we will go to the cart API API forward slash card and let me go to the action method we have apply coupon copy that paste it right here apply coupon looks good let me remove everything else here right here we have the get let me cut that and paste it inside the get card by user ID at the async keyword and if I go to the controller here we have the name of cat card copy that name and I will add that right here forward slash and then we need to pass the user ID that we receive in the parameter we need to change the static detail here that will be the card API base let me modify both of them perfect that looks good let me remove everything else that is related to coupon here perfect now we have the remove from cart async copy the post one here paste that for both the methods and add the asynchronous keyword let me examine the remove from cart async where we have that we are passing the card details ID let me go back here we get the card details ID we have to pass that with the post data the name here let me copy that it is remove card and paste that finally we have the Absurd card async let me go there copy the name paste that here and we are passing the car tto that looks good with that configured the card service is looking good for now let me open the program.ces of the web project I need to configure the service here so let me copy and paste that for HTTP client I have the icard service card service similarly we will have the scope implementation for the icard service that looks good with that we have added the card service in our project and configured our application with program.ces file that looks good in our web project we need to add a controller for the shopping cart it will be an MVC controller let me call that card controller and there we have to inject the card service let me do that with dependency injection the index action let me modify that to be cart index and we will make sure that this is only accessed by authorized user return type here make that async task of I action result and there we have to call the card service and there we have to call the card service based on the logged in user but rather than adding all the code here let me create a new private method right here that will return a type of card tto at the using statement and I will call that load card based on the logged in user then where we have the index view we will return whatever this particular method will return back that will be a card detail now let me work on this method all we need to find here is user ID of the logged in user we can get that from the logged in user we have added few claims there let me add aware condition I will say U goes to U DOT type is equal equal to if you remember I added the JWT registered claims dot SUV that subject will have the user ID I will call first or default on that dot value let me hide this here and perfect that way we will retrieve ID of the logged in user once we have the ID calling our card service is super simple we will say variable response is equal to a weight cardservice.getcard by user ID and pass the user ID we will get the response back the response will be of the type response dto I can modify that here perfect after we get the response back we can check if response is not now and if it was successful then we want to populate a cart dto we can say car tto is equal to we will have to use Json convert dot T serialize object the object will be called dto that is what our API will return back and here we have to convert Dot tostring the response dot result let me return back the card tto and if it was not successful we will return a new car tto with that configured let me add a breakpoint here and I want to see that in action but we do not have a shopping cart let me add that in views shared underscore layout scroll down after the drop down here let me copy one more Li element and we will add that right here controller name will be card controller and action name is cart index let me copy paste that here and rather than typing something here let me add the bootstrap icon here for shopping cart that has the class of bi bi hyphen card we have added everything that is needed to load our shopping cart let me run the application and see what happens we will encounter an error message but let me show that let me open the web project here and let me log in as an admin user if I click on the shopping cart we will see error message because the view does not exist so let me go here and add a debugging point in the response and let me click on the shopping cart examine what the response is if you notice here you will see not found I want you guys to pause the video and analyze on what is wrong I have intentionally left an error in the code so try to figure out on what is causing this error message make sure to pause the video and debug the application I hope you have figured out what the issue is but if not let me do that together let me continue here that is okay let me add a debugging point in the base service and before we send the request out right here let me press enter press F5 to continue here and let me examine the message that we are sending if you look here closely you can notice that we are going to API forward slash coupon and get card this cannot be coupon because we are going to the cart API that should be API forward slash card stop the application and let me remove the debugging Point first and let me examine the card service where we have the get card by user ID I left coupon here and that is why we were encountering not found once you fix that if you run the application you will no longer see the not found I'll have to add the debugging Point again here let me log in and if I click on the shopping cart here perfect it hits the end point but in our shopping cart we do not have any entry for this user ID so it will ultimately throw an exception and written a null shopping cart let me continue here it goes into exception I had a debugging point there and if I examine the response here you can see sequence contain no element and then it returns a new car tto before we continue on here let me work on the logic to add something to the shopping cart from the home page if we go to details we have add to cart we want to make sure that when we hit the add to cart here we call our card API and add item to the shopping cart let me work on that I will close the application let me close all the tabs here we will work on the home controller and there we will have to inject the card service let me add that with dependency injection and we have the product details right here let me copy that and paste it one more time it will be HTTP post let me add that and along with that let me add an action name here to give that the correct name that is product details whoops there we go that looks good now when we are posting here we will receive a product dto let me add that if I go to the view here we have the product dto that will be posted in the view here we do not know which product it is for that we will have to add that in a hidden property inside the form tag that way when the form is posted we get the product ID based on the product ID we will have to populate the card dto now car tto contains card header and card details first let me create that card dto here and there we need to populate the card header that will be a new card header dto inside there I want to populate the user ID I can get that from user.claims dot where and I will add ucos to U DOT type is equal equal to we need to get the subject when we were getting the subject before we used some other constant but we can also use the jwd claim types that is inside identity model we will say JWT claim types dot subject and that will retrieve the user ID as well when I am programming I'd like to show you the different workarounds or different options that way you have multiple ways of getting the user ID now we have populated the card header we need to populate the card details dto that will be a new object there we need to get the count that will be inside product dto.count and then the product ID that will be inside product dto dot product ID we have that in the hidden field we scroll down here we have the input for account and that should populate the product dto dot count finally we need to create a list of card details dto call that card details dtos is equal to new and there we will pass the card details let me call this card details and perfect now this card details dto we can assign that to cart dto whoops card dto Dot card details perfect that way we have populated header with the ID and inside details we added one entity where we have the count and product ID we have to call the response here but that will be on the card service we have the Absurd method for cart async and I will pass the card dto if the result is successful we can redirect them to the index page so return redirect to action and I will say name of we have the index action before I do that let me display attempt data for success and I will write item has been added to the shopping cart perfect if it is not successful we return back to The View with product dto and that looks good let me run the application and see if that works we will log in here as admin let me try to add count of four perfect we can validate that by going to the shopping cart here and we had that query right here perfect new entry has been added and that looks good if I go back for the same product if I add one more entity account will be 5 now that is great if I add some other product quantity of 3 it will add one more Row in the details and perfect our add to cart is looking great if I click on the card here it will retrieve the shopping cart let me see the result here F5 and perfect it has two card details so that is also working as expected in the next video let me create the card index view to view the shopping cart we need to add the cart index view let me close the application here where we have the home controller let me close everything else well I have to work with the card controller I will right click add the view empty View and the name is card index add that now for the designing I have provided that in the Snippets if you go to the Snippets section 9 folder we have the card index UI copy that and paste it right here it will be purely HTML and CSS nothing related to.net core now in the cart controller we are returning back a card dto so that will be the model right here before we modify and make this Dynamic let me run the application and see the UI in action let me log in here as admin navigate to the shopping cart here and perfect we have some product details but we have to be dynamic based on the number of product here we will have to iterate or multiply this line and we have a link to continue shopping and right here we have a link to continue shopping I will add an action method there it will take us to the index action of the controller that is the home controller we move down here we need to display the image right here well let me see I'm not missing anything yep first we need to display the image but that particular div we will have to iterate multiple times I will add the for each Loop there I will say variable card obj in model Dot card details now where will be the closing tag let me find that right here we have the image that will be inside card obj dot product dot image URL we have the product name here that will again be inside card opj Dot product.name and we have the description we will have to convert to html.raw and that will be called obj dot product dot description we have price of the product here I will convert that to the currency format that will also be inside the product obj and finally we have count that will be insert card obj dot count I will scroll down we have an anchor tag here to delete item let me call that ASP action is equal to remove when we are deleting anything in the shopping cart we have to pass the card detail ID we will pass ASP route call that the same card detail ID is equal to and that will be card obj Dot card details ID let me call this card details ID and perfect that looks good for the card detail let me go back here and that does not seem to work let me go back here add a debugging Point here and see what we get back we have a response dto based on that it should have it rated something is not right here let me restart application to be sure before we spend time in debugging let me log in as admin here navigate to the shopping cart it hits our breakpoint continue and there we go we had to restart the application but now we see both the product if I click continue shopping it takes me back to the home page let me continue to work on this in the next video let me continue working on our shopping cart here we need to display the order total and discount total right now in our shopping cart we have not applied any coupon before we work on the order total let me work on adding the logic to apply coupon and also delete any item from the shopping cart let me go back to the code here where we have the apply button right here in that button let me add the ASP action of apply coupon so we have apply coupon here and then if we go to the top we have the form tag without any action so when we hit apply coupon it will go to this particular action when we are deleting any item it will go to the remove action let me create them in the card controller let me work on the simple one here which will be removed I will create public async task of I action result method name will be removed and what is the integer ID that we receive here if I go back copy that name paste it right here we need to get the user ID let me copy all of this paste it here for the constant here you can use the jwd claim type or we have the jwd registered claim name we will retrieve the user ID on the card service we have removed from cart async and there we need to pass the card details ID that will remove the shopping cart if everything is successful we will redirect them back to the cart index so return redirect to action and we will redirect them to name of card index let me add a temp data here for success I will add a message card updated successfully if there is any error let me return back to the view perfect that looks good for remove next thing that we have is apply coupon I will copy and paste that here we have the apply coupon the name here will be apply coupon that will be an HTTP post here and there we will get the card dto when we are applying the coupon we need the user ID as well but we already have that user ID on the card index so in the form here let me add two more hidden properties one for the user ID and next one for the card header ID that way when the form is posted user ID will automatically be populated on the card service we have apply coupon we will have to pass the card dto with that in place let me add debugging point on apply coupon and remove here and let me examine the user ID to be populated I will have to restart the application hot reload for some reason is not working again and it is a blessing when it works but right now also it is not 100 percent let me log in as an admin here we go to the shopping cart here for some reason the intellisense here is not working that's okay let me apply the coupon 10 off apply that and examine the car tto I need the user ID to be populated that is great if I continue here continue There it says cart updated but I do not see the coupon let me validate in database and you can see that did not work something is not valid let me try that again and debug to see what is going on let me examine the response here it says that was successful I will have to do a little more debugging in the cart API where we have apply coupon add a debugging there and I will add a debugger in the base service right here perfect let me continue and let me try that again turn off apply that F5 and let me examine the message it is going to API card apply coupon that seems right it goes to the apply coupon so cart API is being invoked that is good it retrieves the card from the database and for some reason the coupon code is not available right here so cart header dot coupon code is null and that is the culprit debug let me disable all the breakpoint and continue I believe we are forgetting something in the cart index where we have the input field let me see yes of course we do not have the asp4 here that will be cart header dot coupon code simple as that we will have to restart the application our reload is not working let me go to cart and try the 10 off this time it should work and perfect you can see cart updated and we see the coupon right here let me try to delete something from the shopping cart and that also works perfect that is great news now let me display the order total and Order discount we have the order total here I will display that in a currency format and that is inside model Dot card header Dot card total where we have the order discount we will display that only if the discount is greater than zero I will add the if condition if model dot cardheader dot discount is greater than zero only then we will display the order discount [Music] and we will have the currency format model dot cardheader dot discount let me save that and then where we have the button to apply coupon if a coupon code is already applied we need to display button to remove the coupon so let me add an if condition here if the coupon code is not null or empty we will display apply button in the else part I will copy all of them paste it here put the button action will be remove coupon add that here and the coupon code will be disabled I will call that remove here and let me add that endpoint where we have apply coupon let me copy this paste it once again for remove coupon and there we will set the card tto Dot card header dot coupon code to be empty with that let me restart the application and make sure that everything is working as expected let me log in here and if I go to cart we have 10 of discount you can see we have ten dollars remove that perfect that looks good let me try to add few items to the shopping cart here that is working and perfect if I do 20 off now that works remove that invalid code you can see it applies that but the total stays the same so that is on user if they want to enter a valid coupon or not I do not have the button text here something is not valid again let me scroll down and of course let me remove the value here at the closing tag for button right here art reload will not kick in but our card is looking great let me continue from the next video now let me stop the application and let me close all the tabs that we have open then inside the coupon API let me open the coupon API controller and if you remember we commented out the authorized tag right here because what was happening is when the shopping cart API was calling the coupon API we were not passing the better token from the shopping cart API if I run the application right now we will see an exception let me log in here and then if I go to cart here we get the exception right here now of course I can overcome that by checking if response is not null and if responses success then return back else written a new coupon dto that will work but again it is not a solution because with that let me run the application and try to apply a coupon code let me log in here and if I go to cart here even though 10 off is applied you can see the order total we do not see the discount and that is because our shopping cart API cannot access coupon code because it has to pass the better token how can we pass better token that we already have in the shopping cart API to the coupon API when we are invoking that now that is a little bit Advanced concept but let me walk you through that here I will create a new folder let me call that utility in that utility folder I will add a class file and I will be pretty explicit on what it is I will call that backend API authentication HTTP client Handler now that will implement the delegating Handler now you might be wondering what is a delegating Handler delegating handlers are kind of similar to The dotnet Core middleware but the main difference is that delegating handlers are on client side so let's say if you are making an HTTP request using HTTP client we can Leverage The delegating Handler to pass our barrier token to the other request and that is exactly what we want here now better token we can retrieve that from the context accessor so let me inject that with dependency injection then here we have a protected override send async that we can override to access the token and add that authorization header we will not remove the send async because that will continue the flow but before we continue we want to get the access token and add that to the authorization header we will get the token here by await on the accessor we have HTTP context dot we have a method get token async and that will get the token using our default authentication scheme and the name here must be access underscore token that is where the token will be stored once we get the token on the request dot headers we want to add the authorization and that is new authentication header value let me add the using statement [Music] we need to pass the better token there let me do that perfect that looks good let me await here and with that we need to register the backend API authentication Handler I will do that in program.cs file right here I will say builder.services.adscoped we want to add the backend authentication HTTP client Handler and on top of that we are injecting the HTTP context accessor right here let me add Builder dot Services dot add HTTP context accessor now here we have added the backend API authentication Handler that we created but when we are registering that to the service at that point we have to add the HTTP message Handler so right here we will say add HTTP message Handler and what is the implementation for that delegating Handler that is our pack and API authentication HTTP client Handler that will make sure that it will add the token and I will pass that for both product API and coupon API with that let me save everything and run the application now again delegating Handler is a complex topic you can research it a little more but I have given you a brief overview on how to use that let me go to cart here and perfect now you can see the discount order is visible and we can see the order discount our shopping cart is looking great now but if I log in with a new account let's say customer here we do not have anything in the shopping cart if I click the shopping cart we get the exception we have to make sure when we are iterating through each of the object here we need to have items in the shopping cart in order to fix that let me zoom in a little bit right here I will add an F condition F model Dot card header if that is not now and model Dot card details dot we have the count here if that is greater than 0 only then we display the form let me close that right here else we will display please add items to the card let me run the project again and see if that works let me log in as customer here navigate to the card here perfect please add items to the card if I add an item great that is working now if I apply 10 off here it will apply the coupon but you can see the discount is not applied because we have the constraint that minimum should be twenty dollars you can see turn off has a minimum amount of 20 dollars if you add one more item to the card here then the discount is applied and perfect that is looking good when we are programming we have been adding API methods and we have used a weight and async in many of the methods but this async can await is different than asynchronous microservices communication and the reason behind this async and await is when you are using an await key with any of the methods you are basically telling that your thread must wait at this line until a response is being returned from the create update card method that you see in the example that means that if a particular method takes 20 seconds the execution will not go to the next line until 20 seconds are passed and a response is returned back in that terminology even though we are using async await it is kind of synchronous communication because until and unless that execution is not completed the flow will not jump but if this was an asynchronous communication then the line will be executed and it will not wait for the response but because we are using the await keyword we are telling that you must wait for a response before you move forward that makes it synchronous communication I hope this makes sense to you and you do not confuse yourself saying that we are already using asynchronous communication with the update keyword now you might be scratching your head on what exactly and how will we Implement asynchronous communication with microservice let me walk you through that in the next video in this video I want to give you a brief overview of synchronous and asynchronous communication synchronous communication is basically communication when clients sends a request and server responds back before a new request is sent out from the client this is a straightforward approach in a typical application but when we are using microservices architecture it is possible that one service wants to call multiple services on one action without waiting for a feedback that is not possible with synchronous communication because with synchronous communication they always wait for a feedback from the server and only then move on to the next request one positive thing about synchronous communication is that there is always a feedback or acknowledgment of the request being completed but at the same time that might not work with some situations in microservice communication on the other hand we have asynchronous communication and that is when client does not wait from a response to the server basically client will send request and then it will assume that request will be taken care of from that point onwards it does not wait for an acknowledgment on if the request was completed or not because of that in asynchronous communication parallel service calls can be done at the same time since we are not waiting for any feedback about the request completion now let me switch back to an example with the first one that is synchronous communication now there are some disadvantages with synchronous communication Let Me Assume in the architecture here our web project is sending an email functionality where the email service has to send an email but for some reason that logic is taking way longer than expected if it was synchronous communication then the web page will be spinning continuously waiting to get a response back from the email API but if this was an asynchronous communication then it does not care about the feedback and that is typically the scenario when we work with emails we tell them that hey this is the email address this is the content you should send out an email and that's it once we send that message we are done with that and we move on to the next line of execution when email service will have time or when it will receive that message it will start processing that and it will send out an email that is a functionality that user or front-end should not wait on while the email is being sent in that case only thing the sender is responsible is to send a request and forget about what happens with that request now you might be wondering where we have synchronous and where we have asynchronous communication in our architecture where you see the solid lines between microservices those are synchronous communication and we will wait before we return back the response but where you see the dotted lines here all of them are asynchronous communication and we will not wait to return a response Bank an example of synchronous communication is when we are on shopping cart and we have to load all the products we cannot return a response pack of shopping cart without loading the product details in that case the shopping cart API will wait for a response from the product API once it gets the response it will build the complete model and return back and then an example of asynchronous communication is when we are sending out an email once an order is placed we will tell our service bus that hey we need to send an email and we will move on to the next execution we will not wait until the email API picks that message and actually sends out an email main point to remember here is the order API will not wait for the response from the email API or wait till the email is sent customer will place the order and continue to browse the website and email will be sent later when the email API processes the message that means the order microservices is not dependent or waiting until the response is received from the email API it will deliver the message and move on to the next task that is an example of asynchronous communication we will be implementing all of that but I wanted to give you a brief overview and a general idea of how synchronous and asynchronous communication are different another functionality that we want to implement here is email card but that functionality will do is it will typically send an email of the shopping cart now we will not be sending an actual email because for that we will integrate sendgrid and there are some complexity if you are learning with a personal email what I will instead do is when we hit the email cart button we will have a separate service that will be responsible for sending out all the emails and in that service I will actually lock the data inside a database that way if you have to process email you can retrieve the record and send email but sending email is not something I want to cover in the course because it is more prone to errors and it also depends on what email sender you are using for your project but I have given you a hint here that we will Implement an email service that will be responsible to send all the emails across the project not only one service but it will be responsible to process all the email before we look into that let me open the architectural design that we have when we were working with shopping cart we used to retrieve coupon and we also had to retrieve product those Services cannot be an asynchronous service because when someone wants to load the shopping cart we need to instantaneously get a response back from the coupon API and product API to display the shopping cart but now think about email service when you are working on sending an email it is okay if a email is sent out in two minutes or even three minutes typically you do not have a constraint that you need to send it right away or else it will not work and based on that you can see our shopping cart does not directly integrate with the email service we will have something called a service buzz and that is basically a place to store some messages what we will do is on the button click we will add a message in the service bus with all the content that email service will require what service bus will do is it will capture that message and it will forward that to the email service email service when it receives that message it will start processing and it will lock that email in the database the advantage of that is let's say email service goes down for some reason in that case the message will be preserved in the service bus and when the email service is back online it will start processing all the messages that are there inside the service bus service bus is provided by Azure that way it integrates well with the.net framework but there are also other message broker services like rabbitmq and much more first thing that we have to do is we need to create service bus and when the button is clicked we need to send some message inside our service bus we need to create something special that is service bus how do we get started with that service bus is provided by Azure so you need to go to portal.asha.com if you do not have an account make sure to sign up for a free account you get about two hundred dollars in credit with the first time sign up on my home page here I can see the service bus but if you do not see right here you can search for that right here and we have service bus I already have one service bus but we will create a new one for our project similar to any other resource you will select a subscription and a resource Group I will select.net Mastery live project and then service bus is something that is always online and that will be hosted at a URL you can see it is dot service bus Dot windows.net we have to give our service bus a unique name I will call that mango web here you can select the location and we need to select the pricing based on the pricing you can see basic is super cheap but with that we have some limitation let me click the browse here to see all of that you can see in basic we only have cues but when we go to standard along with the queue we also get topics now what is difference between them we will cover them in upcoming videos but let me select standard here because down the road we will be exploring topics with that let me hit the review plus create button validation is successful let me create that perfect deployment is complete let me click on go to Resource and perfect we are on the mango web service bus if you go in service bus we have the mango web right here inside there you can see there are two things in entities we have queues and we have topic let me walk you through them in the next video now that we have a basic overview about q and a topic let me create a queue we will go to queue here and hit the plus button we will give that a name of email shopping cart here and we have few properties that we can configure Max delivery count is 10 but we can keep that as 5 that is okay now queue size you can keep that whatever you want 1GB is way more than enough for our requirements next there is message time to live that basically determines how long the message will stay in the queue before it is expired for some reason if the service that is reading messages from the queue if that fails then it will hold the message in queue for 14 days then we have log duration let's say there are more than one receivers for a queue when we are in the queue if a message is delivered to one of the receiver then it is locked for one minute after that it can be sent to the other receiver you can toggle that time if you want and then we have some other features here and then we have many other Advanced feature like forward message to QR topic in that when a message is received in one particular queue do you want to automatically forward that message to other QR topic if you click that you have to select an existing QR topic we do not want that we will keep things simple for now let me hit the create button and let me create our queue and perfect with that our first queue has been created if you click on the Queue name here we have a service bus Explorer there there you can examine if there are any messages in the queue already you can see right now it is zero that letter basically means that those are dead messages so if something does not work after the five delivery count it will automatically be moved to that letter now we have our queue my goal is when we hit the email card I want to configure a message and write that in the queue for that we need to create an integration service where we can call some method to post some message in the service bus topic inside the service bus queue that we created now I want to implement a service where we will be able to send message in our service bus queue let me stop the application and we will have to create a new service that I will do inside the integration folder add a new project it will be a class Library let me search for that and let me create that I will call it mango.messagebuzz let me hit the next button looks good perfect Now the default class I do not want that I will remove that and I will select manage new get packages when we are working with service bus we have a new get package for that so let me search Power service bus we have Azure dot messaging dot service bus you can see in the description here Azure service bus is a fully managed message broker and using the package here we can send messages to our service bus let me accept and add that perfect in the project here I will add the interface that will be I message bus and its implementation will be inside the class message plus let me go to the interface it will be a public interface and there I want to create one method it will be an async method and I will call that publish message what will be the parameters if you think about that when we are publishing something to the queue we need the queue name and the message that we have to publish we don't know the type of the message so we will keep that as object and we need the name that will be string I will call that topic underscore queue name because we don't know if it is a topic or a queue when we are publishing the message the logic will be the same the only thing we want here is topic or queue name with that you might be wondering that can I have the same name for a topic and a queue inside the same service bus the answer is no if I go back to the code here we have email shopping cart in our queue let me copy that in topic if I try to add the same name it will not work so name must be unique between topic and queue inside a service bus with that our interface is looking good for the iMessage bus I want to implement the message bus right here let me make that a public class that will implement the iMessage Buzz press Ctrl Dot and implement the interface when we have to send a message to service bus we will basically await at a using statement create a variable client and that will be new service bus client that is inside the using statement of azure.messaging dot service bus let me add that and in the parameter we need connection string for our service bus if I go back to the portal here let me go to Mango web and right there we have the shared access policies we have the root policy here where they can perform all the operation if you want a new policy you can of course create a new policy with whatever access you want but the default one is good enough we have the connection string here let me copy that and I will paste that in a string right here private string connection string is equal to paste that now typically what you will do is you will have the connection string in app settings of the individual micro service and then when you are invoking you can pass that as a parameter but for our microservices project we will only use one service bus that is why I am hard coding that here but I wanted to point out that ideally you will place that in app settings pass that down as a parameter or maybe you can have this message bus service in the micro Services as well rather than a separate project you can decide that architecture based on the complexity you have for your project but I am keeping that as a shared project that way we will simplify few things now here we need to pass that connection string let me pass that and with that we have created a client on the service bus client in order to send a message we have service bus sender let me call that as sender is equal to on client we have to create a sender and when we create a sender you can see it expects a queue or a topic name we have that in the parameter which is topic underscore queue name we can pass that before we append the message here it makes sense to serialize that so variable Json message is equal to Json convert let me install the new get package for that dot we have the serialize object and we want to serialize our message the message that we will send will be of type service bus message let me call that final message is equal to new service bus message and there we can Define encoding utf-8 dot get bytes we want to pass our Json message right there we want to pass our Json message there on top of that I want to add something in the parameter here that is a correlational ID it is basically an identifier and I will generate quid dot newquid dot tostring with that we have configured the final message and that will have the Json message that we want to convey in order to send that message on sender we will call the send message async and pass the final message once everything is done we will dispose our client so client dot dispose async that way we are able to publish message to our service bus we want to publish our message and there we want to pass our shopping cart if I go back to the service here where we have the shopping cart API inside the cart API controller let me create a new endpoint to write some message in our service bus let me scroll down here and let me copy this HTTP post that one more time here I will call that email card request that will be the name and from party we will receive the card tto that will be the message that we want to publish let me remove everything else here and in order to get the message bus we will have to configure our program.cs we have the Scope Services here I will add iMessage buzz but if you press Ctrl dot you cannot find that we will have to add the project reference here add and we have project reference we want to add the message bus let me do that and now if you press Ctrl Dart perfect we have the using statement let me close everything else here and in the cart API controller we have to add that using dependency injection let me add that perfect that looks good I will scroll down not cart absurd we have the email card request there we will say await underscore message bus start we have the publish message and that expects two thing first is the message that we want to publish that will be the card dto and next we need the QR topic name we can have a magic string here with the name let me go back that is email shopping cart but that is not ideal ideally it would be inside the app settings.json file there let me create a new section with the name of topic and queue names key will be email shopping cart and value is email shopping cart now the value here make sure it is exactly the same without any spelling mistake we need to access that from our app settings we need the eye configuration and dependency injection for that let me inject that here and we have the underscore configuration let me scroll down in order to get that here on configuration we have get value we will Define the type here and then what is the section name let me copy that to avoid any spelling mistake that is topic and q names go back here key name is email shopping cart make sure to separate them with a colon here and that looks good with that it should be able to post a message to our service bus the only thing that we have to do is invoke this endpoint from the web project that may close all the tabs here and open the web project where we have the card services let me minimize everything else to avoid confusion card service and I card service I will add a new method here call that as email card and let me Implement that when we implement we have to post so let me get that and paste it here we will get the car tto make that an async here and we need the method name let me go back to the API card API method name is email card request copy that and paste it right here that looks good for the card service close all of this here open the web project inside the controller we have card controller let me open the cart index View and scroll down where we have the button email card we have one button here so what we can do is go to the top where we have the form I can write ASP action here and let me call that email card then in the controller here we will have to create that endpoint let me copy the apply coupon paste it one more time that will be email card we will receive the card tto and on card service we will invoke email card if that is successful we want to display the message email will be processed and sent shortly because what will happen is right now it will post message in the service bus we have not written the API that will read messages from the service bus and process all email requests that will be done shortly but right now with all of that let me start the application and see if that works let me go back while the application is running and open the cart API controller where we have the new endpoint let me add a debugging point and go back to the web project let me log in here as an admin let me go to the shopping cart and click the button email card perfect let me examine the car tto here we have everything with the card header but card details is now we can still publish the message here perfect we see that let me go to the Azure portal and where we have the email shopping cart if we click on the service bus Explorer perfect you can see there is one message in the queue and we can pick that message there we have the card header card details is now I will fix that but you can see our message was posted successfully in our card we need to populate the card details but on top of that we also need the email address that way we know that where this email should be sent to you now if we examine the cart model let me go to the web project where we have the card dto open that here in the card header we do not have anything to store email in the future when we place an order we might have more details like what is first name last name phone number email and there might be more things that you want to capture we can always add them in the card header I will make them optional for now but if something changes I will come back and modify that here let me add that in all the card header dto let me search them here card header dto and I will paste it right here as well perfect now let me go to the cart controller in the web project where we have the email card rather than using the car tto in the parameter because we might not have everything I can retrieve the card dto using a weight we have the method load card based on the logged in user at the bottom right here we are getting user ID based on the subject here let me copy that and I will populate the email address right here for email we have the jwd registered claim types dot email that we populated and I will add that in card Dot card header now we have the property to store our email when we are calling the email service make sure to call the cart object that way it will be populated with all the records with that configured let me restart the application and try that once again let me go to the web project I will log in again as admin navigate to cart and we have email card we hit our breakpoint let me remove and continue and perfect let me go back to the Azure portal and if I refresh here grid now we have two messages here and perfect in the second one you can see we have all the details about shopping cart and that is much better based on this object now we can deserialize that in a different email API and log our shopping cart in the email table we have to implement one more API that will be responsible to read all the messages from the service bus and process or lock the email that we want that will be a simple API but let me do the basic Foundation that we have for the other API as well minimize all of this here and I will stop the application create a new project asp.net core web API call that mango.services dot email API let me copy everything from the product API we will start by the new get packages copy that and paste it right here perfect next what we have to do is add DB context in the email API copy the data folder paste that here and I will update the namespace here to be email API we do not want to see it any data there let me remove that in the models let me create a model to log all the records in the models folder add a new class file that will be email logger and it will have four properties ID email message and date time for the email sent that should be good enough for now we want to keep that super simple email logger call that email loggers we need to configure the app settings let me copy that copy the connection string we do not care about API settings or authentication in this API endpoint paste that right here the database name will be mango underscore email let me remove the weather forecast controller we do not want them and the model as well and I will open the program.cs in the product API where we have the default connection copy that and paste that in the email service add the using statement and we do not need anything with authentication or Auto mapper let me scroll down copy the apply migration paste that here and invoke that finally let me edit the project file here remove the invariant globalization and let me add a migration that will be API project add migration add email log table perfect that is done let me insert that as a startup project and run that and once we run that it should create the table let me see we have mango email with one table email lockers perfect with that we have set up the base requirements for our email API but before I end the video the model that we receive here is a card dto to deserialize and read the content we will require a car tto in our project let me copy and paste them as well from the front end here models I will copy card dto card header card details and paste them in the API models let me create a new folder for dto and paste there update the namespace here to Mango dot services dot email API Dot models.dto copy that and apply that for all of them here perfect if I build the project it should work let me double check and we need the product dto as well let me copy that paste it here and modify the namespace perfect we do not need any data annotation let me double check and that looks good let me build the solution build failed again let me rebuild here let me try to run this we have an error here we forgot the closing bracket there we go and perfect and perfect the API is functional now and we have added the dtos as well in the email API my main goal is to read the message that we receive right here and deserialize them we want our email API to be notified automatically when there is a new message in this particular queue of the service bus in order to set everything up there will be couple of videos but let me do all of that right here minimize everything else we are only working on the email API I will create a new folder for that and I will call that as messaging in there let me create a new class I will call that Azure service bus consumer name a self-explanatory here but here we will be consuming the service bus and all the messages that are being sent email API will be the receiver of those messages for that we will require some configuration one thing will be the connection string of the service bus as I said before the itl approach is to store that inside the app settings let me create a key with the name of service bus connection string then I need another section here for topic and queue names there we will store all the topic and q names that we have created and also one that we will create if you navigate to the shopping cart API in the app settings we have one topic and Q name and we know that email shopping cart is actually a cube so let me append the word q at the end that way it is more explanatory on whether that is a queue or a topic I will also update that where we are using that in the cart API controller where was that right here whoops let me modify that and perfect let me copy this topic and q names and add that in the app settings now make sure that the app settings that you are adding is email API I will double click that to be sure and perfect we have added our qname in the app settings I need connection string for the service bus I can go back here service bus and shared access policies let me copy the connection string and paste that right here perfect we have both the constant here and we need to access them inside the service bus consumer let me create two constants here and then in the Constructor we need to get the eye configuration with dependency injection once we add that we can populate our service bus connection string is equal to underscore configuration dot we have the get value we will Define the type here and then the key name let me go back here copy that and paste it perfect that way we will receive the connection string in the Constructor here and we also need to receive the queue name for email card queue let me copy the configuration paste it here we have a section name there and after that we have the key name copy and paste that add a colon between that and perfect that looks good then we have to create a service bus client on the connections ring let me add a variable for that but in the email we will have to add the package microsoft.messaging.service bus we can install that right here in the parameter we have to pass the connection string let me do that once we have the service bus client now on that service bus if we want to listen to any of the QR topic we have to create something called as a processor right now we want to listen to One queue and that is email shopping cart we will have to create a processor for that we will say service bus processor and I will give that a name email card processor let me add an underscore there and we need to set up that email card processor is equal to client dot we have a create processor that expects a queue name or a topic name you can see if it is a queue name it is only one parameter but if it is a topic name then along with topic we have something called as subscription do not worry about that right now we only want to work on the Queue name and that queue name is email card queue that we populated with that we have configured a processor that is right now listening to the queue for any new messages that the queue has to send but on this email processor now we have something called as process message async you can see the implementation is mandatory here and this Handler is responsible for processing the message that is received from QR topic let me Implement that Handler in the next video we need to register our Handler for the processor that we created we can create a method here but typically when we create a service we will be registering that in the program.cs so let me add an interface here let me copy the name first and I will add a new item interface that will be I Azure service bus consumer in here we will create two simple methods start and stop both of them will be async here let me Implement that right here I Azure service bus consumer Implement interface in the start here on the email cart processor we have the process message async plus equal to we want to map a method right here let me call that method on email cart received we have not created that yet but I will do that very soon let me also register another method to the processor but this will be in case of any error how do we want to handle that let me call that method as error Handler let me press Ctrl dot on the error Handler generate both of the methods here perfect now in error Handler we will receive process error event args and that will have the error message that it encountered you can lock that here you can send an email to someone if an error was encountered I am only going to do a console.writeline and return task dot completed but typically you will send out an email that way you are notified when an exception is thrown or an error is encountered main thing that we care about is on email card request received this is where you will receive the message when we receive the message that will be inside RX Dot message and we will have to deserialize that but before we deserialize that we will have to do encoding dot udf8 dot get string we will get that from message dot party if I go back to the queue here and if I examine the service bus the model that we have here is a card dto let me TC realize that here let me call that obj message is equal to we will use Json convert add the package for that dot d serialize object and that will be of type card tto perfect once we do that in a try catch block here we can try to log email and once that is completed we have to do something like arcs dot complete message async that will Mark or tell the queue that hey this message has been processed successfully and you can remove that from your queue in the catch exception you can throw the exception for now now try to log email we do not have a service we still have to add that service let me add a to-do for that but that is great we have configured the start method and we have registered our Handler that looks good let me cut this top here paste that here and when we are stopping we want to update underscore email card processor stop the processing and we will say card processor dot dispose async with that they start and stop is looking good but we need to add that to the container and see how everything comes together we have the start and stop but when should these be invoked the way I want to configure our API is when the API is running start will be invoked and if you stop the API then and only then stop will be invoked that means that API will constantly be listening to the queue for new messages that is how we want to configure and because of that if you think about the lifetime with dependency injection we can add that in a single turn lifetime that way it will only have one copy but we need to register the start and stop and that we have to do that in program.cs we have the application Builder I want to add an extension to that and let me do that in a separate file in the email API let me create a new folder for extension inside there let me create a class application Builder extension we want to add an extension so that will be a static class and that is on I application Builder let me call that as use Azure service bus consumer and for the extension we have to use this keyword and the first parameter will be the application Builder now what do we want to register when the application Builder is being configured we want to add an implementation of the I Azure service bus consumer let me copy that and I will create a private static implementation call that as service bus consumer getter and setter let me add the using statement there and perfect now here we need to get the implementation on the app we can say application Services dot get service and we want the implementation of I Azure service bus consumer we are asking for an implementation here but for that we need to register in the program.cs let me add Builder whoops Builder dot Services dot add Singleton and I will add the I Azure service bus consumer and its implementation and again that will be a Singleton lifetime because we do not want a new object for different requests after that we want an implementation of the service I host application lifetime that will notify us of the application lifetime like when it started or when it stopped so basically on the host application lifetime when the application starts we want to register a new method let me call that onstart and let me copy and paste that again also when an application stops we want to add another method call that as onstop let me create both the methods here and then we are on the final piece on start we will start our service bus consumer and when the application stops we will stop our service bus consumer simple as that we need to make this class static because that is an extension and that looks good now here do not forget to return back app we do not want to hold the pipeline finally we have to add that in our pipeline so let me scroll down here and I will say app dot we will add our extension method and add the using statement perfect with that it has been configured in the pipeline and it will automatically get up and running when the application starts now that we have configured the application extension to start our consumer let me set the startup project as all the project that we have including the email API and let me see what happens I will add a debugging Point let me do that in the consumer I have added a debugging Point only on email card request received that way we will know when a request is being received let me login as customer here and I will add item to the card go to cart click card email for a fact that is done and when we notice in the background here and then if you notice in the background nothing happens it should have invoke the end point let me see something is not right here if I go back here and refresh we have three messages that basically means that our consumer is not working properly it did not hit the end point when a message was there in the queue let me go back to the application and stop the application in the Azure service bus consumer we are getting connection string the queue we have the processor creating that on start we are assigning the process and error whoops right here we also have to start processing that is a critical step so basically where we have the underscore email card processor we have to invoke the method start processing async you can see in the description it says signals the processor to begin processing the message so we need to invoke that only then it will start processing the message with that let me run the application again and see if we hit our breakpoint we already have three messages and perfect you can see it automatically received it here examine the message the message that we are on is the first one with card details as now let me see deserialize that and card header we have that we Mark that as complete right now the first message is complete if we go back here and refresh the queue is now 2. let me continue here now it will receive the second message and that should have header and detail looks good when we complete message async at that point the message will be removed from the queue perfect so with that it is processing all the three message and if I go back the queue will be empty that is great news now our consumer is able to consume all the messages in our queue and now we can add some logic to log our email but with that you can see how everything is coming together we are posting a message to our service bus queue from the API and then a separate API with no direct relation is able to consume the messages that are being posted to the service bus now we need to send email inside the Azure service bus consumer the service bus consumer is a Singleton and the DP context is a scoped service we cannot consume a scoped service in a Singleton implementation for that we will have to get creative and get a new app DB context implementation that is Singleton before we do that let me create a new folder in the email API I will call that services in that folder I will create a class well it will be interface I email service and the implementation will be email service let me make that an interface here and that will have a simple method to send email I will call that email card and log and that will expect a card tto let me Implement that in the email service we have the I email service Implement that interface here we cannot use the application DB context using dependency injection because that is scoped implementation for that we need to register an implementation for email service that is Singleton what I will do is first we will create a DB context option Builder on the appdb context then on option Builder we can say we want to use the SQL server and we have to pass the connection string let me copy and paste that after that on the Builder dot Services we want to add a Singleton implementation of the email service so when we get the email service we want to pass the option Builder dot options once we have that we will have to implement that interface in the email service I selected that so let me go to email service and perfect we have the DP context option that we are getting right here let me rename that to be DB options the private here I will call that underscore DP options and we will have underscore DB options is equal to DB option where we have the function here we will receive the card dto from that let me create a message that can be used as a template for email I will create a string Builder and I will append view lines like email cart request received what is the total and some details about the card now of course you can get fancy with all of the requirements here but I am keeping things super simple let me create one more method here that will be private async task it will be a Boolean log and email there we will receive two things what is the message that needs to be sent and what is the email address let me add a try catch block there in the catch here we will return false else we will return through here I want to create an email logger object and I will populate email and message mail send will be date time.now once we have that we want to store that in the database I will create a local variable underscore DB that will be new app DB context and there we will pass the underscore DB options that will give us an object of the application DB context and using that we have email logger we can add the email log and we will await underscore DB dot save changes you can use the add async here if you want and that should work but perfect with that we are logging the email let me invoke that right here await log and email we will pass the message and the email will be inside card tto Dot card header dot we have email the message here we will have to convert that to string let me do that and I believe that looks good finally in the Azure service bus consumer we have to inject the email service and let me scroll down right here we need to lock that so underscore email service dot email card and log we will pass the message let me awake that with that configured let me run the application and see if that works we have an error here let me see I made a mistake there we do not want the interface here we want directly the email service that is registered with the Singleton implementation with that let me run that and see what happens let me navigate to the web project that we have login here as admin go to cart we have few items let me click email card perfect we hit the end point here let me go to the browser we do not have anything in the queue because most likely it has already been processed let me go to the database and create it already logged that email card and everything worked flawlessly from the web project it sent a message to our queue our email service received that message and it processed and locked that email now again in a real world you could have sent an email to the message and the email address but you can work on the complexities there let me log out here and try customer for a second to see if that is working order total is 28 dollars that worked here and perfect you can see we have customer Gmail and that is also working as expected I hope you guys have enjoyed the free video and you had fun learning the basics of microservices with dotnet corner your journey to microservices has not come to an end I have an advanced course on.net Mastery where we will take the application that we built here and we will add on to that in that course we will explore how to place order and Order management once the order is placed I will be using stripe integration for capturing real-time payments using credit cards storing the session ID providing refunds if they cancel the order and Order management where we will have multiple status for the order we will also Implement role-based management that admin can manage all the orders and a customer can place the order and view the order details of their order then we will explore Advanced Concept in Azure service bus where we will see what is a topic what is a subscription and what advantages they have when you compare them to queues in Azure service bus we will also Implement a new API for rewards API and where we have the image in product right now we are using a URL I will change that to a file upload and make our product API more Dynamic that way it will be able to handle image uploads then I will introduce you to gateways and what role they play when it comes to microservice architecture and we will Implement an ocelot gateway to see how everything comes together final step that I will do is deploy all the application and points that we build on Azure that way you can see how easy deployment is and then as a bonus content I will also show you how to use rabbitmq as an alternative to the Azure service bus that we have used throughout the course so you can see there's a lot more to explore and learn and I hope you will join me in the journey to learn advanced concepts with microservices but before we see each other next time please take a minute to like the video leave a comment and also subscribe to the channel if you have not done that already that way you will never miss another update from.net mastery
Info
Channel: DotNetMastery
Views: 91,971
Rating: undefined out of 5
Keywords:
Id: Nw4AZs1kLAs
Channel Id: undefined
Length: 476min 55sec (28615 seconds)
Published: Tue Jun 27 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.