How To Use HTTP CLIENT IN ASP NET CORE Applications | Getting Started With ASP.NET Core Series

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
when an asp.net application needs to talk to an external service or an api it needs to make an http request this is easily done using an http client class which acts as a session for the http request an http client instance is a collection of settings applied to all requests executed by that instance http client can be used easily but in some cases this is being used incorrectly in this video let's look at some common mistakes made when using an http client and what issues they cause we will then see how to improve the usage of http client hello everyone my name is rahul and welcome back to my youtube channel if you are new here please hit the subscribe button below and help me grow this channel without much delay let's head out to the console and use the dotnet cli to create a new asp.net web api application so using the.net new and specifying the web api this is creating a new template in the current folder let's open this up in an ide i will use rider for this example however you can use any ide that you usually work with i have the application opened up in the ide and here we have the program.cs the startup.cs and the controller by default we have a weather forecast controller which is now being hard coded to return some random values to make use of an http client we need to get data from an external api service in this case let's use a weather api to get data of the weather for this example i will use the api provided by this site weather api i have chosen this for no particular reason other than it has a free pricing tier which allows me to do this demo let's head off to the api explorer to try out this api here this needs an api key i have already created this so let me copy paste that in here let's leave the protocol as http and the format as json so if i was to pass the value of a city as part of q and make a request for the current temperature i can see that in the response here so let's make this exact request and get back the results in our application as well so i'll copy this url because this is what we want to make the request against note here the key is getting embedded to try this you will have to make your own api key so let's copy that and go to the weather forecast controller to clean up the code to make a call to this api since we no longer need these hard coded values first let's remove them we also don't need any of this code so let's get rid of that and in this case i'll return back simply a string and then expose a function to get by city name so let's say task of string and also pass in a city name as the parameter so that's given city name as the value we have the url already copied in so let's use that to make the request in this case i don't want london but i need to pass the city name that comes as part of the controller request so let's make this a string interpolation using the dollar sign and change this london to be the city name for now i will leave the api key hard coded in here normally you would extract this out into a config file and use it from there if you're new to configuration in asp.net core check out the video link here which explains it in detail to make a request to this url we need an instance of an http client so let's make one so our http client is equal to new http client this has created a new instance of the http client we can now make a request to this url using the http client dot get sync called and then pass on the url this is going to make a get request to this particular url so let's get back the response using where response is equal to and add an await since this is an sync call since we added the await let's also make sure to add an async to this method to get this content as a string from this response let's use the response.content and then specify read as string async method so this is going to read the content as a string so let's evade this call and return the whole value in this particular api request so we are simply proxying the request to the weather api and returning that back in here when the application is launched it's by default going to hit this controller endpoint however it will fail because the city name does not exist by default so let's add that to do that open up the explorer and go to the properties and launch settings.json inside here we can see multiple profiles here i'm using the making http request profile to run this you can also click this and choose the other profile which is using the iis express let's pass in the city name to this launch url using the question mark and specifying city name is equal to and in this case i'll give bruce bin by default so if you want this to happen for iis express you'll have to add it for the launch url above here so let's save this and run this application to see what happens so it hits the default url passes in the city name in here which we just specified in the launch profile which is now making a request to the weather api and returning us back the json data which is what we saw in the api explorer as well now this is all working fine so if i was to change the city name and make a request to london this is now going to return the data for london from the outside the application is now working perfectly fine however let's take a look at the network statistics to look what's happening behind to do that i will open the command prompt back again and use the command netstat if you're new to netstat it displays active tcp connections ports and other statistics that's related with the network let's use this specifying some of the parameters from here to see how the network statistics is for the request that we are making to the weather api so let's open up the console and specify netstat and specify some parameters a n o you can check what these means in the parameters table in here the link to netstat is there in the description below so let's go back and make this request you can see there's heaps of data that's coming from the netstat call now we need to filter this so that we can see exactly what we want and the request that's getting made to the weather api so let's go back to the source code and copy the api url so under the weather forecast controller we have api.weatherapi.com so let's copy this go back to the console let's make a ping request to this api host to see what the ip address of it is so let's use that and this specifies the ip address is 185.90 83.2 let's copy that and make the netstat request again and pass the parameters a n and o but this time let's also filter this output using the find str function so in this case we want to filter it by this ip address and we see that there's no request right now so let's go back to our application and refresh this call to the weather api so since this request is again made let's go back to the command line and make a request again now you can see that there is a record for this particular api this is because we made a request to this particular api to get the data from our asp.net web api let's go back again and make another request to see what's happening let's come back to the client again and rerun the netstat as you can see this time we have two more records you can see that there is two ports that's getting opened up here which is on this particular application every time we are making an api call it's creating an underlying socket and opening up a new connection to the weather api now this is not something that we want also note that these connections are still in the established and open condition even though we are done with our request let's go back to the code and see what's happening now in here we can see that we have simply used the http client but not disposed this client you can either explicitly dispose this http client or wrap this whole call inside a using statement so let's do that for now so wrap the whole calls inside a using and make sure we have the braces around that as well let's run this application again to see if anything has changed we have made the first request so if we were to go back to the console and run netstat again we can see we have one request however note that this is now time underscore wait which means it's not in an open condition let's make another request for london and also make another request for texas so we have made three requests in total so let's go to the console and run the netstat again this time you see that there's three requests however the connection status is now time weight the time weight status indicates that we have closed the connection from our site but we have still the connection opened to see if there are any packets that's delayed over the network now if we were to run this again this is going to get disposed of after a default timeout period but for every request that we are making http client is creating an underlying socket so in this case we are going to soon run out of sockets if we have a lot of requests this is usually referred to as the socket exhaustion problem so once you reach the limit of the number of sockets that you can create on the system that the application is running in you will not be able to create any more instances of http client so let's see how we can solve that in the weather forecast controller instead of creating a new http client every time we create a request let's make this a singleton instance to do that let's add a private static property into this class so let's call this private static http client and specify the name as underscore http client there are different ways of making this property a singleton and making sure it's only getting created once to set the value for this instance let's create a new static constructor for the weather forecast controller so let's specify static weather forecast controller and create the underscore http client instance inside that using the new http client let's come down and make sure we use the new http client instance that's part of the static variable so let's remove the using statements and also make sure to replace this using the underscore http client now in this case the http client instance is only created once when the application starts and then it will be reusing that static instance from this class variable let's run this to see how this is working it has made a request to the api and got back to the response let's go back to the console and run the netstat again this time we have a single collection but note that this is still in the established connection state let's refresh this request and make a couple more so let's make a request for london and also refresh that let's come back to the console clear this and run the netstat command again note we still have only one connection opened up to the api and it's still in the established connection this is because we are using a singleton instance which opens up the connection and maintains that throughout the application's lifetime so depending on any number of requests that we make from here so if i was to refresh it any number of times and come back to the next ad and run this it's always going to show 1. now from the outside it might seem that this has fixed all our issues however note that we have an open connection to the weather api endpoint in any case if there are dns changes or other network related changes that can affect the connection this application is then going to fail we will have to restart the application so that it will create a new instance of the http client this is not something that we want so let's see how we can fix this to cater for these different issues related with http client dotnet framework has built-in support to create http client instances this is using the ihttp client factory let's go back to the controller let's remove the private variable and the singleton instance from here and instead of using a new http client let's inject in an i http client factory into this constructor so we can use i http client factory and specify http client factory let's create a read-only field in this class in the get method let's create a new http client instance using the http client factory that we just injected in and calling the create client method this is going to create a http client instance for us let's use that to make the call to the api to register the i http client factory under the startup.cs class under the configure services method we need to call in the services dot add http client method this is going to register an instance of the isttp client factory for this application now that this is set up let's run this to see if this is working as expected the application is making a call to the api we can also change the cities to get this to hit different cities let's go back to the console and run the netstat command again note that here we only have one instance and connection maintained to the api currently so let's refresh this to make sure we are hitting the application multiple times and come back to the net stat and run that again so we still have only one connection and it is still in the established state by using the http client factory.createclient method we are reusing the connections to the external api services so let's look at what the i http client factory is giving us in the documentation url it has massified all these issues that we have seen with the http client and what the benefits of the ihttp client factory is so this provides a central location for naming and configuring logical http client objects we will see that in a second it also helps us to avoid issues and problems that can occur when maintaining and managing http client lifetimes and also the dns related issues that we saw before there are multiple ways of consuming the http client factory what we just saw is the basic usage where we simply called the http client factory and call the create client method on that we can also create named clients as part of the http client registration in the startup.cs using named clients are a great choice when the app requires many distinct uses of http client so imagine you are calling multiple api services in your application in this case using a named client is going to be more helpful so when using a named client we can set up some of the common properties for the http client instance right up front in this example let's see if we can extract this out as a base url for the http client using the named client method let's remove this base url from here and go back to the startup.cs method in the place where we are adding the http client let's use a name for the client in this case we'll name it weather let's configure the httpclient instance defined here let's specify an action delegate which is going to take the http client instance in this case we can specify the base address to be a new uri and pass in the value that we just copied so this is going to set the base uri for this client whenever it's resolved using this name to start using this in our application let's go back to the controller and instead of simply calling the create client let's pass in the name weather so this is by default going to resolve the instance that's created by this registration here this is also going to have the base url set automatically let's try and run this to see if this is working as expected the application is running and it has successfully made a request to the api let's also make a call to london and we get back the data as expected let's go to netstat and see the request and this is also as expected from before when using name clients you can also configure the http client to specify default headers or anything else that's common to all requests made to that api the next consumption pattern that we will see is called typed client in the name client we were using string names such as weather to refer to the client instances now this is something that works however in case you want to remove that you can use a typed client so type client provides capabilities without the need to use strings as keys and it also provides other benefits as listed here so let's see how we can refactor our code to use a type client so let's go back stop this application and add in a weather service class so let's open up the solution explorer and add a new class which is called the weather service so this service is going to help us to make calls to the external weather api i have the code already written out so let me copy paste that inside here we have an eye weather service interface which has one method to get by the city name so this is implemented using the weather service class which is using an http client as before so this makes a request to the api using the api key and the base url is again registered elsewhere so going back into the weather forecast controller instead of taking in an i http client factory let's now take in an eye weather service and call this weather service let's make sure to create a read-only field to store this and remove the i http client factory which we no longer require so let's remove that let's clean up this code and make a call to the weather service and return using the get method so we can pass in the city name and return this and add in an await to register the iweather service let's go to the startup.cs and in the add http client let's remove this named registration and specify a typed registration to do that let's specify the iweather service interface and also specify which class is implementing that particular service in this case weather service the rest is as before so we are overriding the base address to be this url so let's run this application to see if it's working as expected let's make a request to london and it returns us the data from london let's go back to the netstat and make sure that we only have one connection and that's still in the established state no longer are we depending on string names to resolve the http client the weather service is taking in an http client instance which is directly getting injected because of this startup registration call so if you are talking to multiple apis you can create multiple ad http client calls and specify those services in here whenever we are using the i http client factory it is an http message handler which is getting reused so this message handler class is what is responsible for creating the socket connections so here you can see we have the controller which is getting injected in a service in our case this was the i weather service which also takes in an i http client factory since we registered it using the type client we didn't have to explicitly pass in a factory but the dependency registration service took care of this for us the http message handler instances is getting reused across the multiple calls that we make to this particular service this is why we only see one socket getting opened for this application throughout its lifetime the connection pooling makes sure to timeout these instances regularly so that the dns changes wouldn't affect our application i hope this helps you to understand better on how to use http client instances in your asp.net core applications we have seen the issues of directly creating an http client instances and how to solve that using the i http client factory we have also seen the different consumption patterns that you can use with the http client factory if you like this video please make sure to hit the like button if you want to be notified of future such videos please make sure to subscribe thank you and see you soon
Info
Channel: Rahul Nath
Views: 14,262
Rating: undefined out of 5
Keywords: asp.net core httpclient, httpclientfactory in .net core 3.1, httpclientfactory, httpclientfactory in asp.net core, how to use httpclient in dotnet, Using HttpClient in .NET Core to Connect to APIs in C#, using httpclient c#, aspnet httpclient, httpclientfactory asp.net core
Id: bAXZx0zOeCU
Channel Id: undefined
Length: 20min 10sec (1210 seconds)
Published: Wed Oct 07 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.