Using HttpClient in .NET Core to Connect to APIs in C#

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
how do you safely connect to API is in dotnet core HTTP client is the way to go but doing it right is important otherwise you can exhaust your connection pool and cause issues in your application and your computer in this video we're gonna connect to an external API in Blaser server using HTTP client to see what our various options are for getting data from the web now if this is your first time watching a video of mine my name is Tim Corey and it's my goal to make learning c-sharp easier one of the ways I do that is by teaching context there are logit Oriels out there that will teach you what to do I go a few steps beyond that to show you when to do it why you should or should not do it what pitfalls to avoid and what the best practices are basically I get you ready for the real world if that is the type of training you're interested in subscribe to my channel and hit the little bell icon to be notified when I release new videos okay let's head over to visual studio and we're going to create a new project in Blaser it's a new project and right out here Blaser app and now that we have a new release we actually have the option of Blaser server or client or web assembly so let's call this our HTTP client demo and we'll call his client dental app ok and the option here is now Blaser server or blazer webassembly app this is the Blaser client so they've kind of gone back and forth now they're gonna call it web assembly and that's we'll use going forward so we're gonna choose a blazer server because this is the the web product type that how does I would assume that you will start to default to I know I have it's just kind of the best of both worlds both the server and the client so you could also choose a razor pages project in asp.net core or MVC dotnet core or even API in dotnet core there's a lot of different options you can choose but this will work just fine let's hit create and we're going to do is we write a small API that I have that's on the web it's not mine personally but I've got a URL to a little weather service API through our connect to that so let's start off by going into our startup CS file this is where we're going to configure some services now this is all for dependency injection in dependency injections built right into asp.net core projects if you're using a console or WPF core or wind form core it is there to have dependency injection it's just not enabled by default so you can still have it and this HTTP client will work in those scenarios as well so just note that this would work in any dotnet core product type not just the one I'm showing you all right the first we're going to do is just say services Dodds add HTTP client and it's as simple as that what that's going to do is it's going to add an HTTP client factory into our dependency injection system that way we can access it at any point so now we're at do is we're going to add one nougat package this nougat package is not required but I'm going to use it because it greatly improves how you work with HTTP client there's a bunch of extension methods that adds that just make things into one-liners instead of multi-line configurations that we're often gonna forget so let's go to dependencies and this is actually from Microsoft it's not a necessary third party it is system net dot HTTP JSON and so this provides extension methods for the HTTP client and content that perform automatic serialization and deserialization using system text son so this is a newer package it was actually published the latest version was published on May 18 2020 that's the version I'm using version 3.2 point O so install that and this just makes like I said life easier so that's all you need to have for NuGet packages okay and now we can do is we can create our our page let's go to pages and when I right click here and we'll add a new razor component now it's on the the right-click menu which is nice or you could go to new item and go to find razor component but just note this is a razor component not a razor page there's a difference a razor page is a server side only page that's not what we want in a blazer application a blazer application is composed of razor components so razor component you get the dot razor extension onto the end of this and let's call this weather data now we do have another component already built in to our template called fetch data that's going to get weather forecast service this is something totally different so just note that it is different but it's going to still get weather information this one's going to get from an API though now let's start before you start modifying this page we do need a model to put this data into so let's right click on our project and say add new folder will call it models and in here we're going to create a new class and we'll call this class weather forecast model how about that but what properties we have well we don't really know yet right because we haven't even looked at what the API call is so let's do that now I've got a API source I'm using so it's pasted in here it's meta weather calm does not require a log and it's a pretty simplistic service but it's a really nice service and the fact that it has HTTP it doesn't have cores or cross-origin requests on there so we can just call it directly from our API so therefore we can just run this and this is for the closest location to me which is Philadelphia so doesn't have every location but this one is in the eastern US time zone and the location is Philadelphia sorry that that's a little small there how about that a little better so this is the request you get back from this particular API call now this this number right there that is the the whoa ID wo e ID for Philadelphia you can look up your own if you went to Meadow weather.com and just search for your location so I'm gonna copy all of this JSON data because that's what it is that came back from that call now I'm gonna do is below this class I'm not gonna do it inside a class below this class let's say edit paste special paste JSON as classes this is an awesome feature what this will do is once it's run notice I had just created multiple classes in here we have the root object we have a parent we have consolidate whether we have source class alright if you look at the properties in here you'll see sunrise sunset time zone name title location type lo ID lat lon time zone and so on so it's got a whole bunch of information in here that all comes from that API so what does it read that JSON data and said ok here are the things you have in here for example there's an array of consolidated weather items so that's the property name and then it gave a class name that matches that property name is just that this is relized so the name 'is not great it's not necessarily a c-sharp specific and we could fix this and could tweak a lot of it we'll do a little bit of that just to show you how you'd how to do it but the reality is that I'm not going to clean up all the way because I don't need to spend time on that portion of it so just note you can decorate these and say okay they're bringing is JSON this is the JSON name but here is the c-sharp equivalent of that name for example I wouldn't call it consolidated whether with an underscore I have a capital C in capital W probably but then I couldn't have a class name be the same thing so there'd be some tweaks to it so let's first of all rename root object I'm gonna rename it the weather forecast model like so and delete this other class so now we had weather forecast model and this consolidated weather let's change that let's collapse parent here consolidated weather let's change this to day forecast model because this is uncontrolled dot to rename that which also renames it up here so what this is is all the weather for the various days I believe is like a five day forecast or something like that so give you five different days of of information on things like the min temperature the max temperature the wind speed the direction of the air pressure humidity visibility and so on so we're gonna keep that we do want that but some of the stuff we don't need for example time we don't need that so let's get rid of it time zone name I believe that was the one that said lat long we don't need the time zone not time zone name just time zone is potentially important so let's keep that one but will not keep these other things down here will keep the title and we'll take out source and parent don't need those don't need time zone name so we grabbed a few piece of data notice I can just delete this stuff if I don't want it to be captured it won't be it will just capture what properties that match what's in the JSON returned values so I don't need a parent class at all so let's get rid of that I also don't need a source class down here let's get rid of that as well so now I have just two classes I have the letter forecast model which is the the overall model and then inside there it has a list of day forecast models which are the different days it's forecasting so let's go through the day forecast models get rid of ID we'll keep letting a state name take out the abbreviation the compass it created to have those three properties applicable date that means which date the forecast was for so let's keep that min and max temperature we'll keep that note that that is in Celsius so those of you the US it'll look a little different but no worries you could convert that if you wanted to again it's outside of scope of this demo let's take the other things off I don't mean to have all that data just do a state name the applicable date min max temperature okay now we could do if you want to fix some of these things for example title well actually a capital T normally you can control dot and fix the name violation as long as it changes just the casing you don't have to decorate this class and say what the JSON equivalent value is it will take care of the capitalization without a problem so again we can fix timezone but notice Suns sunset I fixed that it just capitalized the the Sun not the set because an underscore not our normal naming convention so that would be something whoops there we go there'll be something I would address in a real application by decorating these okay again outside a scope this video I just want to show you you can do at least this much and make it a little bit closer to a c-sharp specific formatting ideally if you control the API side of it as well you would send it without the underscore that way we could match them up without having to do anything beyond just change in the casing okay so the way I would send say sunrise is I would send it as Sun Rise like so that'd be a JSON version which we then would change to sunrise and would match the C sharp casing so you could do something like that very easily but the underscore is here it makes things a little Messier but again I don't control this API all right so there are my two classes I can break this off into its own class file controlled dot move type to a model dot CS there we go so now I have two models and the one we're going to use is this forecast model which will then contain this other model all right so in here what we're gonna do is we're going to create just a really simple little page that's gonna get this as I call this API on the page loads and it's going to load all the information about the the forecast so let's start off by giving it this page a name so at page and if you're not familiar with how Blazer server works I've got an intro to blazer server that would be really helpful a video on that that will walk you through all these things in more depth I'm just basically touching on the high points here with again it's outside of scope of this video but I do have a video covering all this content as well as of course the course blazer server in depth which would go in a lot more detail this stuff okay so page would be let's call this the just call it weather all right that's the URL for the page so the you know localhost and the port number of slash weather will give us this page before we go any further let's go ahead and add this to our navigation it's going to copy this and say weather here probably an H in there and there's the the link to it let's change the icon that's right now a list and there's a whole bunch different ones you can choose I don't things an actual weather icon so we can do I like doing this just run up for a little bit and then hold you know and stop well now we've got ash there's one called random so let's there's a random one all right it's not that right icon but it's great for demos so so now we have a link to our page we can actually go to it when we launch this directly okay so you can launch you can see the navigation the left we click on it goes right to that page now this is where the HTTP client stuff starts we want to inject this is how you do dependency injection in a blazer server or even blazer client project is you do an at inject on the page in this case I'm going to inject an I HTTP client factory let's call it client factory and then we're going to do is down here in the code section I'm gonna say protected override I'm gonna override the on initialized async that it has had problems with a formatting for a while they're working on it it's tricky to get formatting right in a blazer server page but just know that that is something that is on the list of things get fixed so I initialize async this will run after this is injected after the client factory is injected before the page is rendered so that's the important thing is you want this if possible to run right away so as soon as the page is initialized after this is filled up with you if you ran it in the constructor then you wouldn't this would be null this client factory so that's too too early to run it and if you wait to the page is rendered then that's kind of too late so you want to run it on on initialized ace now if you have server rendering turned on for some blazer clients then you might have the potential to run this twice there are ways he can check for that but it's not usually an issue okay we also don't need to return based on initialize async we can ignore that so in here we're going to do is we're going to use our HTTP client in some way so first I'm going to say var request and create a request equals new HTTP request message this is one way of doing I show you a quicker way but I want you to full way first because there are times in the quicker way won't work you need to use a full way so so create a request message first and this is going to be a HTTP method Dodd's will do a get notice we have all the different verbs here get post put delete head there's patch down here as well so we want a get command so it's gonna get information and then I'm going to pass and let's do the next line just just a little more space I'm gonna pass in I finished still have it in the clipboard I do not now I do there we go so there is our URL to call so that's the that's the URL that I called I pull it up here right here so I pass in these this URL and I get this information back if I change this number I would get a different location back alright so now we have our request set up and I'm going to do is now create a client so I say var whoops var client this is our HTTP client equals client factory dot create client and what this does is use the factory to create client for us and so it will either from exist an existing client out or it will create a new client depending on some internal rules there is a pool of clients that the client factory has that it will pull from the reason this is this is important instead just create our new a new HTTP client every time is because you can actually have socket exhaustion from having too many open clients if you don't close them properly plus it caused some overhead in your machine it was just a little messier to just call HTTP client directly well now using the client factory we can create these clients using the factory which properly creates them and properly make sure they're closed and all the rest so we want to worry about how it is disposed of a dispose of itself just fine and it refreshes them on a certain cycle so the DNS does not get stale but it also doesn't have too many open at a time it just it takes care of a lot of stuff behind the scenes this is kind of like what async/await does for threading where he has a lot of stuff going on behind the scenes there's a lot of rules behind the scenes how it works but at our side we just say you know oh wait so in this case on our side we just say create client and it will create the client or give us an existing client we don't have to care at which so now we can say HTTP response message response equals a wait client dot send async and here's the request to send so it's gonna send the request out and get a response back yelling Lee because I have in a wait but no async up here I often forget that you have to mark an override async even if it always would be async alright so now we have our response message but we're not really done yet it's if response dot is success status code I feel look to make sure that it's a success which means at 200 or 201 there's a few other possibilities for the return type but if it is then we can do something to get that data so let's come up to the top here above protected override and we're going to say weather forecasts let's go weather forecast model and it says HTTP client demo dot models that will have forecast model notice how it's show up in tell a sense even though we don't have a using for this that's kind of nice now I could add the using up here or what I can do is go over to imports and say at using HTTP client demo Dodds models and that will then ensure that models are available without a using statement on any of my pages I may do that instead let's call us forecast like so I'm not gonna initialize it I'm also gonna add a string error string where I use that in just a minute if we don't have a success err success status code so now I have my forecast now I can do is I can put the value in here so forecasts equals a weight response dot content dot read from JSON async and as the weather forecast model like so but I do I am missing a using statement here as well so let's go back to imports and I believe it's at using system dot net HTTP died JSON that's the one we brought in our our nougat package so sojanet GP JSON that's the extension methods and sure enough that's the only one so what that's gonna do is it's gonna take our content and it's gonna read from JSON async which means gonna take this model and it's gonna read the JSON JSON and put it into this strongly typed model we'll get back forecast which is a weather forecast model this just shortens our path to getting our data back into a strongly type model that's that extension method does notice the icon here it's a little small but its icon indicates an extension method so let's do an else here and just for complete or sake of completeness we're gonna say error string equals there was an error getting our forecast okay something like that we could if you wanted to grab the response dot status code let's just make it strain tribulation we'll do a colon and then say let's grab something from the response response dot reason phrase okay so I think as the reason phrase for what the error was if there was one so this is how he creates a client and then how we can use it to make a call notice this is a get call we could do a post or anything else since it's a get call we're getting data back therefore we can do read from JSON async but even even if he weren't getting data back we could still do this is success status code now let's do one little cleanup thing here gonna say error string equals null here just in case we have the error string already populated from a previous attempt and maybe we do a second attempt something like that but a null this out if the forecast comes through properly so now up here we're going to do in my HTTP section is I'm going to say if string dot is null or whitespace on error string equals false so is something in the error string then I'm going to say div class equals h2 to get me that size that I want and just say error string with the this is the Razr syntax to allow me to put c-sharp code here so if it's an error string show that else if forecasts is null so as no error string but the forecast is null that means we're still waiting for that forecast to come back therefore div class equals H for something a little smaller here just say loading now this is where I typically put some kind of gift or something like that to indicate load from here we'll have one more else and this would indicate that there is no error and there is data in the forecast that's what this else indicates it's or a create a little table to show some data table class equals table and table striped like so and then we'll create T head with a class equals T head dark I like the dark header it makes it look a little nicer and a row inside here and th inside here for date and then another th for weather State that's the you know is a cloudy partly cloudy windy those kind of things th not HT and this is going to be the low as in the low temperature for a day and T age for the high as in the high temperature I'm not indicating Celsius versus Fahrenheit because it's all Celsius again you could translate those and and have your your two different numbers if you want to t body again this is just a show-off that's working that's all I wanna do here so at for each not forecast at for each I look at that snippet and play for each let's say W in forecast dot consolidated weather so this is the the list of weather items in there so let's go back to our weather forecast model we have consolidated weather that's the property that has that list of day forecast model so I grab that and say for each one of those let's create a row where we'll have a few T DS let's grab this going to copy it and let's do four of them there we go at W Dodds this is applicable date the intellisense here and at W dot notice it it gives you intellisense for brunch everything which is a little frustrating but once you start typing it figures out oh this is this is the the object you're talking about actually so what a state name there we go so at W and now it actually figured out after a couple attempts here this is the min temperature of course it's it messed up the placement of that there we go it said this is a little difficult for the team to figure out how to make all these different pieces work together and make intellisense intelligent when you're mixing so many different languages and systems together so they do a pretty good job they're still strolling on blazer a little bit so there's our table we haven't put anything about the the overall data which is things like location which the title the zone the Sun right in some set I will skip that for now because this is just a demo to show that it works it's not a full demo show how to create a weather page okay so this should give us all we need to see if this call works let's run this and see what happens so I run it I'm ran I asked Express which means it will give me a a different a different port number then you might have that's okay my port number is 4 4 3 4 4 kinda nice port number let's go to weather notice there's that random icon it says loading and that pops in and according to this in Philadelphia on 527 of 2020 they had showers and the low was eighteen point eight and the high was 23 tomorrow it's getting light rain then shower is more showers heavy rain and then light clouds starting on the 1st of June so there's our weather forecast note that it first said loading and that popped on to this page to it that if statement is working let's now just make a little tweak to this and break the URL they come down here and my URL right now it's the valid URL but what if I change this number and add two zeros at the end that's probably not valid let's try it again and see if we can't get a different value here for our weather that's loading and that says there was an arrogant our forecast not found that's the message if you look at the error code it would say 404 so that's we haven't found our forecast for this location which is understandable but now it shows that our error message does work and it doesn't throw an exception here when it can't get a valid response so this isn't gonna throw an exception if you have a 404 it's going to put that into your response message you need a check for that and then if it's not successful do something with that that error so what I said that was the long way of doing this let's comment all this out so we can have that I'm gonna put the source code in a link if they give your email address that's kind of our exchange here you want to pay their email address you get the source code of this video you can have this and player in that directly or of course you get his title from a screen that's fine but what I'm gonna do here is that commented all this code out and now I'm going to say VAR client again equals client factory dot create client okay so it's same exact code of before but now what I do is I have a try catch and we'll have exception e acts like so I'm not gonna throw it and in here I'm gonna say forecast equals a wait client dot get from JSON async weather forecast model and I'm gonna pass in that full URL which lets copy that full URL from up here whoops let's take off the double zeros that make it invalid they're ghosts there's that full URL which we can unpin this so you can see the full thing so that's one line this one line replaces the create the request and get this async back and do this but notice that since it does all of this including this line right here what happens if you don't have a valid response back saying here's some data what if you have a 404 well that's where the try-catch comes in we wrap this is going to throw an exception if we don't have valid data coming back so we can do here is say error string equals and let's actually just grab this right here a copy all of this and pay down here but instead of reason a phrase I'm gonna say ax dot message and again I will in here say error string equals no so that these lines right here are the equivalent of all of these lines up here alright so it is a lot of well some saved work here it saves you how to remember how to do the is successed as code and all the rest you do the more common c-sharp method which is a try-catch we're kind of used to that so this could be an alternative for you let's run this and make sure it works the exact same way even though I changed pretty much all the code solo forecast loading and there's your forecast so that did work now we're going to do is we're going to make us a little better you see right now I'm passing the full URL in well that's even a simple version of calling API because sometimes you have to add things like headers where you say you know here is the authentication token or here is my client profile or my client ID those kind of things in the headers well this isn't dealing with any of that so let's make our lives a little easier let's go over notice instead create client we're actually going to create named clients let's go over to our start-up CS and in here we have add HTTP client I'm going to add new one let's say services dot add HTTP client but this time gonna say it's been called meta ok because that's the service name is meta something meta weather okay I'm gonna call it meta and then I'm gonna pass in the configuration so say C for configuration our arrow and then inside of here we're gonna say seed I'd base address equals new URI and that URI is going to start with HTTPS as wws meta wthr.com slash API slash so that's the base address we can also do things like see and then have our default request headers or add a request header those sort of things response headers it's a bunch of stuff we can put in here if we want to configure our API but that's all I need to do what this does it creates a configuration that can ask for by name and now this also has our base address which means that to call this I just need to put whatever is on the end after slash API so with that let's come back over here to our weather data and instead of doing this this way I'm gonna say meta like so and that requests a client that's of the type meta or it's named meta now I can take off all of this I don't remember the whole URL just the ending of that URL what this also makes really convenient is if your API ever changes locations you can change it in one spot now normally what you do is and startup you'd probably be pulling this from configuration not hard coding it into your your c-sharp code so instead of doing this you'd probably cut this out he'd say configuration dot get value of type string and then let's I just let's get him a name it to it let's call this our API our meta API it's not like that and then over in our app settings dot JSON we can say meta API is whoops Wow let's try it again there we go made an API like so so now it can even pull from our configuration but only pulls once it's not like it's pulling every time we do a call because will you set it up once ok so now this is a named HTTP client knows I still have this HTTP client as well you could have multiple so that you can have multiple named ones and a default one that way you don't have to always use a named one maybe you have a one-off call you on make well you can do it by saying just HTTP client know name and then give it a full path but this way it's configured for us let's run this again just to verify that in fact it does work as intended let's run this go to whether there's an error no such known house okay so it doesn't work excellent let's find out why my guess is it has something to do with loading from our configuration so just to kind of verify I'm gonna say string URI equals this right here and I'll put a breakpoint in here let's just first make sure it's pulling from the configuration right this is debugging step 101 okay it's first make sure you have some values coming through so URI is it's got four double use in meta whether com that ain't right so let's go ahead and stop this and now go to app settings dot JSON and fix that let's go back to startup make sure that breakpoints off is let's run us again and see if it works okay so debugging one step at a time it may not be the only problem we have it was cool but do one step at a time figure out and verify each step don't assume that the step is correct okay that was reading properly from the from a config file so I could have said oh I know it's reading the config file right so therefore it can't be that well yes it can because I put the I type something wrong so don't assume steps just take it one step at a time and debug those issues okay so this now works it's pulling from our named configuration and we've now shortened how much we have to actually put in here to just the extension of our API so I mean after the API slash so that's why all there is to using HTTP client using the factory set up properly and using the extension method nougat package allows you to make really easy calls just that one line or call that you do the wrapping a try/catch for exception purposes but otherwise you don't have to remember all this setup stuff like the HTTP request message and then the response and the success that has code and so on so this just makes life a little easier now there's not every extension known for this extension method class so not everything will work there's not I believe all the verbs aren't covered if there's a couple that aren't so in that case you revert back to the standard way of making the call up here okay so either will work but this allows you to use the client factory you can use a named instance or not and using this will allow you to safely talk to web applications okay I think it's all for now I do y know if you have any questions about this or any it kind of doesn't make sense or stumped you we will be covering in a future video talking about cores so the cross origin and how you can deal with that whether you control the API or not that's a future video coming out but until then if you have any other questions let me know down the comments below that's the best way of asking for a new topic or an addition to an existing topic ok thanks for watching as always I am Tim quarry [Music] you
Info
Channel: IAmTimCorey
Views: 96,442
Rating: 4.9464192 out of 5
Keywords: httpclient, httpclient c#, httpclientfactory, httpclient factory asp.net core, httpclient c# tutorial, iamtimcorey, tim corey, tim corey blazor, tim corey dependency injection, blazor server side, blazor server app, system.net.http.json, system.net.http, .net core, asp.net core, .net core 3.1, .net core 3, c# api, c# api call tutorial, c# api call, http requests c#
Id: cwgck1k0YKU
Channel Id: undefined
Length: 45min 2sec (2702 seconds)
Published: Wed May 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.