Web API Project Address Book with source code in GitHub | REST APIs | C# | Web API Best Practices

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
foreign [Music] we are building an address book web API and I'm using visual studio 2022 Community Edition if you don't have Visual Studio you can download it for free and this is the website I'll put this link in the video description let's start building our project I'm gonna go to file new project and here in the menu I'm gonna choose c-sharp all platforms web API and this is our project asp.net core web API I'm going to choose it I'm going to click next and I'm going to call it address book API I'm going to leave this unchecked I don't want my solution in project on the same folder click next here I have options for framework and I can choose.net6 LTS long-term support or dot in 7 standard jump support and I'm gonna keep it at net 6 because usually when you work for a big company you stay with long-term support and when another release comes long-term support you just upgraded so next long term support will be that net eight so when it comes out you can always upgrade it to net a directly and it lasts for three years versus standard jump that lasts only for 18 months so.net6 and I'm going to configure for https so secured connection and I'm not going to keep it in a container so I'm Gonna Keep it unchecked so I don't want to enable Docker and here I'm Gonna Keep it checked I'm gonna use controllers I don't want to use minimal apis and I'm gonna use open API so it's going to be check too and I'm not going to use top level statements so all the three options will be checked I'm gonna click create this is my project that was created and on the right side in solution Explorer I have all folders and files displayed and what is great it's actually a fully functioning project I'm gonna close this overview window and let's run our application and I'm getting this Swagger interface so what is Swagger and why do we need it in the previous video when we discussed web apis we were talking that web apis don't have any user interface it's just sitting on the server and waiting for HTTP requests here we actually have some kind of user interface this Swagger interface Works only in the development environment and in the past you would actually have to download the package and do some configuration to have Swagger UI nowadays when you create a web API it actually comes pre-configured let's look how it was configured and then we'll talk about how it works so I'm gonna minimize it and to have this Swagger API working let me actually stop the application and I'm gonna right click on on this address book API project and I'm gonna go to manage nuget packages and here on the installed tab I can see that we have a swashbuckle.asp.net core package installed so in in the past you would actually have to go to this browse Tab and type swashbuckle and you would click on that and you would have to install it so let me close it and after you install it you would go to this program CS file and in the past you have two files program Cs and startup CS files and inside you would have to configure everything so here you have everything configured already so these lines and these lines are the lines that you need to put in your program CS to make the Swagger work so let me start the game and let's see how it works so right now in a template we already have one endpoint and the weather that is coming from this endpoint is not real just random data that weather controller spits out for you we're going to look at it in a second but the way it works we have the name of the controller so this is weather forecast and this is our end point here I can actually try it out and I can see the schema so I'm gonna click try it out and here I'm gonna click execute I have client URL information here and I have request URL so this is the request URL and here I can see the response so 200 it means it was a success and this is what I'm getting from my web API let's look at the structure of our application so I've already looked at our program CS file we also have this app setting Json file and if you expand it we have also app setting development Json we're going to use these files to keep the connection string when we add a database to our project let me close it if you go to properties we have this launch setting Json file and this file defines how our project is going to start depending on an environment so as you can see here the development development and here you can see that swag is launching only if we are in development environment now we have a model and this is for our weather forecast controller and it just defines a few properties and our controller inside the controllers folder is the controller that has only one endpoint so this is our get method and here it generates some random data to show where the project is running we don't need these two files so let's just delete them I'm gonna right click delete and same I'm gonna do with the controller kill it and let's add our own controller I'm gonna right click on the controller folders add controller and I'm gonna make sure that I'm on this API option I could pick this empty option but I actually like this template I'm gonna click add and I'm gonna click right here and remove values and type context add our control is created and if we choose the empty template we wouldn't have all this information here let's start and see if it works it's done successfully and we're not gonna test it because it's all diameter let's actually try our get method and as you can see we just have Diamond data returning to us in the response body let me close it and let's start working on our controller first of all I want to rename all these method so I have get get by ID posts we usually use it to create a new object put we use it to update our data and delete we use to delete our data let's rename it so instead of get I'm gonna say all contacts for this method I'm gonna say contact by ID for pause I'm gonna say create contact for put I'm gonna say update contact and here it's going to be delete contact I'm going to save it Ctrl s and if I start our application we still don't see our change methods let's fix it I'm gonna close it and to fix it I'm gonna add something here in our router attribute so after this square bracket I'm gonna put forward slash and in square brackets I'm gonna put action all these methods in our controller they're called action methods and now after I start the application it's gonna find and recognize this action methods names I also don't want to have this API prefix in our URL so I'm gonna just remove this API in forward slash if you want you can leave it there it's not going to change anything I'm going to save it Ctrl s and let's start the application and as you can see now we have all methods here in the URL let's go back and we're going to start implementing our method one by one let's create folder for our models I'm going to right click on the name of the project add new folder and I'm going to call it models enter I'm going to right click on our folder add class and I'm going to call it contact add and inside our class I'm going to add a few properties I'm going to type prop it's a snippet I'm gonna press tab and I'm going to leave our type as int again tab and I'm going to call it ID I'm going to press enter twice and I'm going to do the same thing prop tab here the tab is going to be string tab and I'm going to call it first name and I'm going to press enter twice and then tellsin is helping me so I'm going to press Tab and it's again helping me and it's asking to initialize it to an empty string and I'm gonna do it I'm going to press tab again enter and here I'm gonna actually copy paste it three times I'm gonna press Ctrl C and Ctrl V twice and this one I'm Gonna Change to phone number and address the last one and I'm going to add this empty string initialization to the first one I'm Gonna Save it and let's go back to our controller I'm gonna keep all my data for now here inside this class and I'm ready pre-typed it so I'm gonna just copy paste it and we're gonna talk about it so it's a private static list of contact objects and I called it context and here I initialize an instance of this list and inside this color braces let me unpin it I have three objects an address here is underline let's see what happened there and it looks like I misspelled it I'm Gonna Save it again let's go back the error is fixed and let's first Implement our all contacts get method so context Ctrl C and I'm gonna just replace the whole thing here Ctrl s and it's underlining and it's because the return type is not the same at the John typos of our list so the way we're gonna do it I'm gonna remove this return type and I'm going to add a John type I action result this I action result allows you to return different results back so I'm gonna type okay and put this context in parenthesis and what is going to happen when we check our result okay it's going to give us 200 result success and it's going to give us the list of these objects let me replace all return types and all methods with I action result I'm gonna copy it Ctrl C and I'm going to replace all of them here I'm also going to remove these comments I'm going to press Ctrl X let's move to our next method contact by ID we are getting this ID in a URL and this spelling must match the spelling of this ID now we're gonna use this ID to find the object in a list of these objects so I'm gonna type bar contact equals and I'm going to type context this is our list and I'm gonna use a link method first the default it's right here and I'm gonna press tab and I'm actually going to rename this x to contact you can call it anything you want and I need to replay this x to contact two all right after we found this object we need to make sure it's not null because if we pass ID number four it won't be on the list so let's verify until someone is helping me here so I'm going to press tab if our contact is null we're gonna return a bad request and here inside this parenthesis we can add a message and we can say it cannot find this contact otherwise we're going to return our contact and we need to put it inside let's go to the next method in our post request we're gonna get all the information from our body and we're gonna send here our contact object and let's call it new contact here let's create a new object we're going to call it contact and we're going to say new contact and intellison is helping me we're going to populate the properties of this new object and we're gonna get those values from right here I'm gonna just press tab for all of them here doesn't give me anything let me just type it now intellison works again and after we create this contact we're gonna add it to our list contacts after that we're going to return okay request and we're gonna return our newly created contact let's go to our update contact we're going to restructure it a little bit we don't want to send this ID in the URL and we're gonna do the same thing like we did in the previous method so we're gonna get this object in the body of our request and here instead of newly just call it update contact now to update the contact we need to first to find this object in the list and we have already this code so let's just grab that I'm gonna copy Ctrl V and instead of ID we need to say update contact dot ID if we can find this contact in the list we are going to send better bad requests and we can say cannot find this contact to update otherwise we're gonna update the values for that contact and intellison is helping me again here we don't need to edit we're just updating it and at the end we're gonna return and OK response with our updated contact let's Implement our last method the idea is going to become in our URL and before we delete it again we need to find it so it's going to be the same piece of code right here and this we need to replace it with ID now and let's change the message you cannot find this contact to delete otherwise we're gonna take our list and we're gonna remove the contact we found after that we're going to return our OK response and let's send a message the contact has been deleted let me save it and let's test our application Let's test our first method all contacts I'm going to click try it out execute as you can see we got all three objects on our list Let's test our contact by D method try it out and if I try to execute it's going to give me an error because the ID is required let's just found an object with id2 as you can see we got an object with id2 let's create a new contact try it out and here we need to send some information I'm going to say id4 and I'm going to just change the first stream to test execute and this is our newly created object id4 and apparently I misspelled test let's use that misspell to try to update the contact so I'm gonna try it out and I'm gonna say id4 and I'm gonna change all values to test execute and you can see our object with id4 has been updated let's set the last method delete contact and I'm gonna delete the contact with id2 execute and we have a message the contact has been deleted let's stop the application and now we're gonna start improving our basic web API at the moment we have so-called fed controller all logic accessing our data and retrieving our data is right here in our controller to make our controller thinner we need to move it in a separate class and usually those classes are called Services we can call it anything we want but to stay consistent let's call it also Services there are a few reasons to keep our controller thin one of the reasons is to have those methods and services available to the whole application so for example if we have multiple controllers multiple Services we can call this method contact by ID from different parts of the application so it will comply with the dry principle don't repeat yourself another reason to separate it from our controller is that if we want to update how we retrieve data or what type of database we're using we can just implement it in that service and our controller will be untouched so we're separating our concerns let's go to our solution Explorer I'm gonna pin it to the screen and I'm gonna create a folder right click on the project name add new folder and I'm gonna call IT services enter I'm gonna now create a new class I'm gonna right click on this folder add class and I'm gonna call it context service press add and now we need to move all logic from our controller to this class I think it's easier if we just copy everything and modify it I selected it and I'm gonna click Ctrl C let's go back to our service and I'm going to make some space here and I'm gonna press Ctrl V Batman pin our solution Explorer so we'll keep our list the same and let's start with our all contacts method first of all I need to remove this decorator so I'm going to just press Ctrl X I'm going to rename this method I'm gonna call it get all contacts and it's going to be returning the list of our contact objects and of course here I just need to remove this okay this method is done let's go to our next method I'm going to remove this again and in this method we're gonna just return a single object so it's going to be contact and I'm going to rename it also get contact by ID I'm gonna remove this okay again so we're going to return that single object and here I'm going to actually remove this if statement this first or default method returns null if we cannot find an object in this list so in our controller we'll just have to check if this object that is being written is null or not so for now let's leave it like that let's work on our create contact remove this we're returning a contact so here instead of I action result it's going to be contact again now the data is not going to come from the body because it's not HTTP request so I'm going to remove that this logic is okay the only thing I just need to reach on our contact object update contact same here let's remove this HTTP put the return type is going to be contact we don't need this part here we need to leave this if statement because if we can't find the contact on our list we cannot update it so let's do a little swap if the contact is not null we're gonna do all this I'm gonna press Ctrl X I'm going to remove this control B and at the end I'm gonna return our contact so return and if it's null we're gonna just return now we're going to trade here let's go to our delete contact so we don't need our decorator here instead of returning action result we can actually rich on a Boolean so here if we cannot find the contact if it's null we're going to return false otherwise we're going to remove that contact and we're going to return true I think this is it let's go back to our control and modify so here we don't need this data now we don't need this list to access our methods in our class we need to create an instance of it we'll do it right here inside this method for now but later we're going to change it so I'm gonna say bar and we're going to call it service equals mu contact service and it's right here on the list double click as you can see Visual Studio add this this using statement to here so I need to add parenthesis semicolon and inside this parenthesis I'm gonna actually call the method we created I'm going to say service get all contacts parenthesis and this method is done let's go to the next one now to get that contact I'm gonna call it service so I'm going to say service get contact by ID and I need to pass that ID intellisense is helping me so we're going to pass this ID to this method the rest is going to be the same let's modify next one I'm going to just copy it this is our create contact I'm going to remove all this logic because it's already another method and I'm gonna get our newly updated contact calling our service update contact and we're gonna pass this object to our method I should check if that contact is not null so let's just review this code and I think this method is done let's modify our update contact so again we're gonna create an instance of our service let me remove this and we're gonna call our service and the method would be update contact and we need to pass this object there we don't need this and this endpoint is done let's move to our delete contact endpoint we're gonna delete this I'm going to just press Ctrl X again we're going to create a new instance delete all this service dot delete contact and we're gonna pass an ID semicolon now this delete contact method it's actually returning a Boolean let's call this variable result instead of contact let me copy it and replace this and we'll say if our result is false we're going to return the bad request otherwise if it's true we're going to return okay the contact has been deleted so I think this is it let me save it I'm going to press Ctrl s and let's start our application Let's test our all contacts endpoint try it out execute we have all our contacts contact by ID try it out to execute we got our object create contact try it out let's just put ID seven and we'll just change this one to test execute so as you can see we got this message cannot find this contact to create so the implementation is wrong let's fix it really quick let me stop it back to context service this part looks okay let's look at our controller and here in the create contact controller we use the wrong method so instead of update contact it should be create contact Ctrl s to save let's start let's try it again create contact try it out let's make it id10 change one of the strings execute so this is our new object update contact let's update our second object execute object with id2 has been updated and the last one delete endpoint let's delete our object with id1 execute Enviro message the contact has been deleted all endpoints are working how they're supposed to work so let's close our application and continue improving our project at this point we have a fully functioning application everything works however this line 17 is considered a bad practice to make our application better we're going to talk about dependencies and dependency injections so what is dependency we have our class context controller and inside our class we are creating multiple instances of this context service if something goes wrong with this service our context controller class is going to break too so this class context controller depends on this class context service in contact service classes can see it in dependency let's look at couple examples of how changing this service will break our controller let's say tomorrow we decided that we need to pass a user information to this class let's go back to contact service when we work with our data in this service we want to make sure that this data belongs to that user that is logged in so one of the ways we can send the information to this class is using the Constructor we'll talk a little bit more about Constructors but for now I'll just create one really quick so I'm gonna make some space here I'm going to type c tour tab and here in parenthesis I'm gonna say string I'm gonna just call it username so we are passing this username we're going to create a private field here let's make it read only and we're gonna say it's gonna be a string and we're gonna name it username inside our Constructor we're gonna say username equals our username now we have this private field that we can use in these methods when we extract or update or delete the data let me save it and go back to our context controller and you can see all this lines when we instantiate this class is broken now of course we can fix it so let's say we're going to get that username from a token and we're going to put it in a string at this point I will just hard code it and we're gonna use this username when I create an instance of this class so our code is fixed here now we need to go to all other methods and do the same thing so what if we have 20 controllers with 10 different methods and also what if tomorrow instead of just passing username we want to pass the username and the role of that user we'll have to do the same work go to every single controller and every single method and change it again first it's a lot of work and second by doing it we might do something wrong misspell something or delete something by mistake there's another scenario where this method of coding could cause some problems let me undo all this what I've done I'm just gonna press Ctrl z a few times I'll undo it here to win a service save it Ctrl s and for our next scenario I'm gonna go to solution Explorer and I'm going to create another service better contact service this better contact service will replace our contact service the reason we have this better context service because we decided hypothetically to change our relational database to a non-relation database this better contact service will have the same methods inside but with a completely different implementation when we are done creating this better contact service we want to go to our contacts controller and replace all these instances so here we'll have to come and say the contact service and of course we have this underlining line because we don't have this method there and to replace all these instances we have to go to every single controller and every single method and replace it dependency injection will fix it for us let's talk about it let me undo this Ctrl Z I'm Gonna Save It Ctrl s and to start with dependency injection let's create a Constructor here I'm gonna type c tour Tab and this is our Constructor Constructor math is the first method that will be executed when this class is being instantiated we know it is a Constructor because it has exactly the same name that our class after we create a Constructor let's create a private field and all variables inside the class are called Fields so I'm creating a private field and I'm going to make it to read only and I'm going to make it a type of context service and we can call it anything we want I'm going to put an underline in front of it and here inside our Constructor I'm going to create an instance of this service this is a little better because instead of creating an instance in every single method we are creating it in one place and after we created this instance Ctrl C I'm going to replace this one and I'm going to remove this let me fix the misspelling as you can see our code works again before we do further modifications let me use this instance in other methods I'm gonna use it here here and here I'm gonna remove the slides let's go back up this is better but we are still creating an instance of that class right here inside a better way is actually to send this instance to this class from somewhere outside and that's what we call dependency injection we are injecting the instance of our service to our context control class dependency injections are built in into.net framework if you go to this link you can read more about how it works and what you can do with dependency injections for now let's implement it here first thing we need to go to this program CS file and we're going to add a service here we are going to say Builder dot services Dot at transient and inside this triangle brackets we're gonna put our contact service Visual Studio helped us and put this using statement right here parenthesis and a semicolon so what we did here we created the service that will give us an instance of this class anytime we requested let's go back to our controller and here in the Constructor in parenthesis we are going to say contact service and we can call it anything you want I'm going to call it just contact service and here inside the body of our Constructor I'm gonna say equals this part wouldn't work without this configuration let me go back let me save it and let's test our application to make sure it works and as you can see the application is still working let's close it in our next step we are going to create an interface and we're going to talk about why we need interfaces and how we could use it specifically for our project before we start looking at interfaces let's fix couple of things first thing I noticed that for this method I didn't make the changes that we did for other methods so here we still have an instance of this service so I'm gonna delete that and here instead of service I'm gonna say contact service let me save it and the second thing I want to look is in this program CS file when I add this line for our dependency injections we never talked about what add transient means let me make two copies of the same line Ctrl C Ctrl V Ctrl V and I'm gonna change it to add sculpt and this option will be at Singleton so right now we are using a transient option and what it means for every single use of our service a separate instance of this class contact service will be created and right after this instance is used it's going to be discarded usually when you work with databases that's what you want you create an instance use that instance to get the data and you discard that instance in some more complicated cases in a single HTTP request you call multiple methods in the same instance so in this case you should use the adscorped option and the last option at Singleton is not used very often but in our case we might actually need to use it so what happens right now let me change back to transient Ctrl Z let me save it Ctrl s if I run our application and I'm gonna update one of the contacts try it out and let's update the first one with an id1 I'm gonna just leave it like that test string string string I'm gonna press execute and if you look here it looks like our object was updated now if I run other all contacts method try it out execute you can see that here our object was updated too the reason for that is because inside our contact service we declare this list as static if we remove the static word let me stop it save it and start running it again let's do the same thing update one test execute so it was updated now I'm gonna get all contacts as you can see the object with id1 it looks like an original object now if we go back to the project let me actually stop it go to our program CS and change it from transit to Singleton let me save it start the project so if I update my contact same thing execute has been updated and here if I run this method as you can see now my object is updated and what happened every time we request an instance of our service let me go back to visual studio and let's go to our controller we're gonna get exactly the same instance of this class so this is the difference between transient scoped and Singleton options in dependency injections let me switch everything back I'm gonna change it back to transient save it and I'm gonna change our list back to static and now let's talk about interfaces if we go to this website and look at the definition of an interface it says an interface defines a contract any class or struct that implements that contract must provide an implementation of the members defined in the interface let's create an interface and see how it works there are a couple ways you can create an interface first you can just click on one of your folders add new item and here you can find an interface change the name we're gonna call it eye contact service add and now we have it another way to create an interface you can go to that class that you're going to be using it with right click on the name of the class go to quick action center factoring and you can click extract interface you're gonna get this model and here I can just click OK and I won't just get an interface I'm also gonna get all these members based of what methods this context service had let me click OK and we'll look at it it's called eye contact service one because we already have eye contact service let me open it so we have an empty interface that we created and we have an interface that was generated from our contact service class first thing let's talk about the naming convention you don't have to but it's best practice if you prefix the name of your interface with a capital I also in the body of your interface you can have properties and methods and not just methods only method definitions you won't have a body so here we have the return type of our method the name of the method and the parameter of the method in the next one the return time is Boolean the name with delete contact and the parameter is an integer that we call ID so for a second let's forget about this interface and let's just use this one that we created manually so how do we use interfaces first of all you don't use it without classes or structs and once you create an interface you can implement meant it so let's go to our contact service and since we use this refactoring option it already implemented it but we're not going to use this interface let's just start from scratch so we're going to put column and we're going to type I and we're gonna type eye contact service and remember this interface is an empty interface so what change if we run it application compiles and nothing really changes now let's add something to that empty interface and we'll see what happens here we're going to go here and we're going to create a definition for a method and in this method we're going to find all contacts that live in student CD so first we need to put a return type so there might be multiple contexts living in the same city so the return type is going to be a list of our contact objects so let's put it there so this is our return type we're going to click on it and I'm going to press Ctrl Dot and I need to import this using statement and now our interface knows where to find this glass contact next we're going to provide a name for this method we're gonna call it context by CD and the parameter is going to be a stream and we're gonna name it CD so I'm gonna save it and remember our class implement this interface so if I go back to my contact service I have this underlining line and if I click right here I will have this option Implement interface so if I click on it the underline is gone and if I scroll all the way down I have this a newly created method and as you can see this method has the same return type least contact the same name context by CD and the same parameter Siri I don't have here anything yet inside the body and this line will make sure that I don't call this empty method by mistake and if I do an exception will be thrown so as you can see an interface forced our class to have this method let me do some restructuring before we continue our conversation so let me just remove this method because we're not implementing it and I'm gonna remove it from here too and I'm actually gonna grab it from here all those method signatures Ctrl C and I'm going to place it here Ctrl V so I'm going to save it I'm going to go back to our contact service and as you can see this part is fine because now we have all this method implemented that we have in our interface and I don't really need this duplicate eye contact service one so let me just delete it and now what we're gonna do we're going to do the same thing with this empty class beta contact service that we created earlier and I'm gonna actually implement the same interface it shows me the underline and I'm going to implement interface and now I'm gonna have exactly the same methods as I have in this service let me save it so this is the first usage of interfaces by implementing this interface you can make sure that certain classes would have certain methods and properties now the second and I would say the most important feature that now you can use this interface to create an instance of this class let's see how it works let's go to our controller and do the following I'm gonna say eye contact service and you can see I get help so I'll just press Tab and I'm gonna call it contact service and I'm going to change this part I'm gonna say new contact service let me change this a little bit I'm going to call it contact service instance so in this line I created an instance of this class but when I indicate the type of that instance I use our interface this instance will work exactly the same if we use just a class instead of this interface so contact service instance and you can see we have all these methods now available so let me change instead of I context service I'm going to change it to contact service I have same result so why exactly do we need it to instantiate our class to create this instance using this eye contact service interface let me delete all this and I'm going to do something here on line 13 instead of saying contact service I'm going to say eye contact service I'm going to do the same here on line 15. and technically for our code nothing changed we are still getting this instance using dependency injections so the setup is right here and we assign this instance right here now let's add something else in our program CS file right here in line 12. we are going to change context service to eye contact service and here I'm gonna put the comma and I'm going to say contact service so what we did here we are saying that in this line we are going to create an instance of this class using this eye contact service interface again nothing changes it's going to work exactly the same and here the best part as you remember we were talking about this ballet contact service that we created earlier and this better contact service would have different implementation for these Methods at some point when we want to switch this contact service to this better contact service all we need to do we can come to this program Cs and here on line 12 we can just replay this contact service with better contact service I'm going to save it and start the application and as you can see it's successfully compiled of course the endpoints are not going to work because we don't have an implementation let me show you it went to this method of this better contact service the point here is just with changing one line we replace the implementation and used an instance of a different class this is what's called loose coupling we are injecting an instance of this class context service class but this class is not tightly coupled with our context controller class let me stop the application and let me go back to our program Cs and change our class from better contact service back to contact service next let's talk about dtos I'm going to include this link in the description of this video about dtos and DTR or data transfer object is used to transport data from backend to front end there are a few advantages to using dtos and will demonstrate on our application specifically the second point hide particular properties that clients are not supposed to view let's go back to our application and I'm going to create a new folder right click on the project name add new folder and I'm gonna call it dtos I'm gonna right click on it and create another class and I'm gonna call it contact dto add and I'll go to my contact class copy all these properties Ctrl C go back Ctrl V now we have the same classes with different names why do we need the second class let's pretend that in our contact class we have an additional property credit card number let me add it here let's leave it to the string I'm going to save it and let's go to our contact service and add that property here to our objects I'm Gonna Save it and now if I start our application and get all contacts I'm gonna get credit card number information with everything else what if we decide this credit card number information is sensitive and we don't want to expose it to our users let me close it one way we can do it in our contact service before we return our data we can go through the list of our contacts and assign it to an empty string let me save it and start the application right here we still have credit card number but the value is an empty string the problem here is that we are still exposing this property to the front end user and if we don't want that exposure we could use our newly created DTR let's go back to our application here in our contact detail class we don't have that extra property so instead of using our contact class as a return object we can use our contact detail class let me go back to our service and here in line 15 instead of contact class I'm going to use contact dto class control Dot and I'm going to bring this using statement right here now before I return it I need to convert this list contact into list contact details the different ways to do it we will do it manually but there's actually a nuget package you can load and map those two classes to each other in one line here let's just do it manually first I'm going to remove this because we don't need this line anymore and I'm going to create a new list of our contacts using contact detail class and I'm gonna Loop through our context list inside the loop I'm gonna create a new contact detail object and I'm going to map all properties of our contact object to our contact detail object and as you can see we are not bringing our credit card number and property because our dto simply doesn't have it after we have this object we're going to just add it to the list and after this list is created we're gonna pass it back to our controller line 7 shows an error and it indicates that since we adjusted our method we need to go to our interface and adjust it here too so on line 9 instead of contact it's going to be contact detail I need to bring a using statement save it let's go back to our contact service and as you can see the line is gone Let's test our application to make sure it still works now we also have a narrow inside our beta contact service class I have to adjust it too save it and let's start the application we're gonna test it to make sure it still works and as you can see we're getting the same data but without that credit card number property let me adjust everything else to our new implementation with contact zto I'm gonna first change it here I don't really need this class better contact service but I'm going to keep it for now let me save it go back to our eye contact service interface and I'm going to adjust everything here so here is going to be contact detail contact detail and contact detail save it now let's go back to our contact service we need to change it here too I need to adjust all this first of all we're gonna pass this contact dto object and after we update our list we're gonna map this updated object to our dto so it's going to be similar to here so I'm going to just grab it here we're going to create a new dto object and map it here at the end I'm going to return dto let's go to the next one here after I get this contact object from the list I'm gonna map it again very John contact detail and we also need to verify if our contact is not null and if it's not null let me change it to an exclamation mark we're gonna do all this and if we can find it we're going to return null in our control we'll have to verify and if the date is now we're going to return a bad request let's go to the next one here after we update our contact we are going to map it to our dto and we're going to return our dto let's look at our update contact method and now let's look at our eye contact service interface as you can see we need to update this contact class to contact detail class save it let's go back the underline is gone let's go to our controller we're going to change this to contact dto same here Let's test our application and of course we need to change our better contact service to contact to dto and this contact to dto2 save it start another arrow and it looks like it's right here it's finally working how it's supposed to and as our schema if you click here you can see instead of using our contact class we are using our contact detail class in The Next Step let's talk about data validation there are a few Microsoft articles that describe model validation I like this one and I'll put the link in description of this video this is the.net validation tool that helps you validate data coming into your API even if we validate data on the client side we always should validate data on the server side we could potentially do it manually in the if statement checking if let's say our first name is not empty string but it's much easier to use this built-in model validation tool let's scroll down a little bit and look at our if statement where we validate our model we also need to look at the validation attributes there are quite a few building validation attributes and in our application we're going to be using this required attribute and string length attribute the setup is relatively simple so let's get started on it let's go back to our application and since we are using our contact detail to send data back and forth let's go to that class and let's add our attributes to our properties I'm going to start with the ID square brackets required and I need the using statement so I'm going to just click right here to import this system component model data annotations since all our fields are required I'm going to add this required attribute to all of our properties Ctrl C and I'm going to press enter here Ctrl V same thing for all the rest the other data attribute we are going to be using is string length and we're going to apply it to all properties with the exception of our ID property so square brackets string length and my first name is actually going to be 50 symbols or less same thing we're going to do for our last name for our phone number is going to be 20. and 200 for our address property let's save it let's go back to our site go back up and this is the if statement we need to add to our controller action methods I'm going to press Ctrl C let's go back context controller and here where we are sending our data in the body we're going to make some space and we're going to place the block of code and if the model is not valid we are going to return a better request the great thing about this that we don't need to include any messages here all messages about model validation will be attached to this bad request automatically so this is our create contact method Let's test it I'm going to save it and start the application create contact trade out and here I'm gonna add an id5 and I'm going to make this first name an empty string let's execute it let's look at our response and you can see the code is 400 and in our response body we have errors property and inside we have a narrow forward first name the first name field is required let's look at couple more errors we are going to make the phone number a very long number and we're going to have an address as an empty string execute let's look at our response and now we have errors for our address first name and phone number let's stop our application and adjust our methods let me copy this piece of code Ctrl C and I'm going to add it to my update contact method and now I delete contact and another contact by ID method we don't need to do that because if this ID is not being sent inside URL this method would just not be found that's all for model validation and now let's move to our asynchronous way of programming our action methods in our controllers this Microsoft website gives you a great overview of all asynchronous programming scenarios and let's considered the best practice to make your action methods in your web apis asynchronous every time you access data in databases or load data from files you don't want your application to lock and wait for the results back and that is why you make those methods asynchronous let's go back and look how it works there are three steps to make your action methods asynchronous first we're gonna add this async keyword and then make a return type as task of type I action result after that when we call our methods when we get data from the databases we're going to add this keyword await and of course we would need to go to our service and change it to make it a synchronous at this point right now an application doesn't make sense to make these changes because all our data is available instantly since we're using this list inside our service but when we add a database and connect it to our application using Entity framework we will convert our methods into asynchronous methods let me undo these changes right now and at this point our application is completely finished I hope this video was helpful and thank you for watching [Music]
Info
Channel: DK Programming
Views: 586
Rating: undefined out of 5
Keywords:
Id: a5cgN453zs8
Channel Id: undefined
Length: 65min 39sec (3939 seconds)
Published: Wed Oct 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.