Check out a free preview of the full C# and .NET Basics course
The "Making HTTP Requests" Lesson is part of the full, C# and .NET Basics course featured in this preview video. Here's what you'd learn in this lesson:
Spencer discusses how to make HTTP requests using the HTTP client in C#. He explains the different methods available, such as GetStringAsync and GetAsync, and how to use the HTTP request message to specify the HTTP verb, URL, headers, and body of the request.
Transcript from the "Making HTTP Requests" Lesson
[00:00:00]
>> Spencer Schneidenbach: Okay, making HTTP requests another common thing that we will do, we already kind of did, actually, we not already kind of did, we actually did, inside of our code here. We nude up an HTTP client, and then we called GetStringAsync. There's a few other methods that you'll need to know to use HTTP client effectively because it's not just made up of GetStringAsync, there's actually a ton on HTTP client.
[00:00:26]
First, it's important to mention that HTTP client is async all the way down. I know I mentioned that already, but it's a good reminder. So the methods that call them should be declared async as well, all the way down as if you can. And so it's really just exists to be a high-level abstraction for making HTTP requests and processing HTTP responses for those requests.
[00:00:48]
So one construct, one such construct that we will see a lot of in the ASP.NET course is the HTTP request message. So this is the thing that contains all your HTTP headers. Who made the request? Or where did the request come from, right? What resource are you trying to access?
[00:01:04]
What host are you trying to get to? What headers are on this request? What is the body of the request? That all comes from the HTTP request message. So when we're using HTTP client to make those requests, this is typically what it looks like. We would typically go HTTP request message, it say, here's the HTTP verb I'd like to use and the website that I'd like to download.
[00:01:24]
I'll new up my HTTP client, and then I'll call send async to allow me to send this raw HTTP request message. There are some other things. There are other some other methods that kind of make that a little easier. You don't have to use send async, you can use for ret = await client.GetAsync.
[00:01:48]
You can use GetAsync here to actually go and get it, and that will automatically create an HTTP request message with the right URL in it. And you can see that all the way down to as you navigate through the source code, you can see that's the case. Again, it won't let me navigate any further than that wooden rider, though.
[00:02:07]
Okay, if you have a let's say that your connect your comment, you're interacting with a common API or some other service. Maybe it's Azure, or maybe it's something like SendGrid. You may have a situation where you need to add a request header to every request typically for authentication.
[00:02:27]
So you might have something like this where you need to pass in order to make this service call, you may need to say, hey. I need you to send this API key, or this header with every single one of these requests. So you can do that by an HTTP client just calling default request headers.add so you can see that here, default request header.
[00:02:47]
So this would be basically that any call GetAsync, PutAsync, PostAsync, any of those verbs that are made, any of those requests that are made, will automatically throw that header onto that request. Correspondingly, if you need to authorize using the authorization header, that's easy to do. The authorization of the default request headers has an authorization header object available to it, and this is how you would set it.
[00:03:15]
You'll see lots of times when you're talking to other APIs that you're using bearer tokens. So you might say new authentication header value, and then you would give it the bearer, which is known as the scheme, and then the actual token that will be sent to the client, that will be sent to the server, excuse me.
[00:03:35]
So we've already kind of talked about GetAsync, but there's a couple of things once you do GetAsync. So, when we got GetStringAsync, obviously that just downloaded a string, but the type for GetAsync is all different. It's actually quite a bit different. So, the type for GetAsync, you'll see.
[00:04:01]
We hover over it is an HTTP response message. So HTTP response message is the abstraction that represents all of the things that came back in that HTTP response. What are the headers that came back in that response? What's the body of that request? And oftentimes when you're interacting with these APIs, you'll say something like I want the content of the request and you'll say await client or sorry response.client or content.
[00:04:28]
And then you'll see a couple of things. You'll see the content is HTTP content is of type HTTP content. And you can read it as a stream. So you can read it as a stream of bytes back. You can read it as JSON. So if you're getting a JSON blob from that API, you can read it back and put it into a .NET object, which I'll show examples of that in the ASP.NET course.
[00:04:53]
You can also just read it as a string, which is functionally equivalent to what we did before when we called GetStringAsync. So that's taking the body of the request. Quest, and just just taking that, reading that content and putting it into a string into memory. So functionally, the same as GetStringAsync.
[00:05:09]
And then, of course, when you need to make mutations to target systems, you make good you can use HTTP client to make put or POST requests. Which would be to say that if you wanted to add in a blog post via an API or something, you might create a JSON blob with that content in it, and then post that off to the target server.
[00:05:34]
We already mentioned, read from JSON very useful, like I said, for receiving JSON blobs back read as string or ReadAsSreamAsync. I have used this recently a lot for getting files back from an API. It'll probably be something it would be something like blob storage, and these are audio and video files.
[00:05:54]
These are media files. So I want to make sure that I'm being respectful of the resources the server that I'm at. So I'll take that stream. I'll take that stream, I'll open it up, and then I'll literally send it off to another caller to send them that file inside of a stream.
[00:06:08]
So I'm not taking up 200, 500MB of memory. That would just be terrible practice. A couple of other things on response IsSuccess status code, so all HTTP requests respond with a or a the response contains what's called a StatusCode. 200 level status codes are considered good, considered our mission was a success.
[00:06:37]
300 is typically some kind of redirect. 400 as you get into error territory. 500 is bad error territory. Well not typically, anything that's in the 200 to 299 response code range is considered a good thing. And this would be considered IsSuccess status code two true. There's a lot of times that I use this if I know that an API may be flaky or I need to make sure to log to make sure that this API call succeeded or not.
[00:07:05]
I'll use IsSuccess status code to log that or make sure that I checked status code to make sure that it was successful before I do some kind of processing on that response. EnsureSuccessStatusCode is a method that will throw an exception if the re ResponseStatusCode is not indicate success.
[00:07:22]
I almost never use this, simply because I think that in many cases, in this one included, there's just cleaner ways to handle the error state from an API. And throwing exceptions, I can usually handle it more gracefully. Somebody earlier masked about resource exhaustion if you create one HTTP client per request.
[00:07:43]
Yeah, you can absolutely exhaust system resources. So you don't do that. So typically, in most in an ASP.NET Core context, you're gonna use an abstraction called IHttpClientFactory to create them for you. And it manages all the goodness under the hood to make sure you don't exhaust system resources.
[00:08:00]
Other than that, you will typically take one shared HTTP static or HTTP client that's static, and you will share it across your entire application and you just will never dispose of it. Which is important to say, because while I said that disposing is important, there are some things you do not want to dispose HTTPClient tends to be one of those things.
[00:08:20]
Now, if you do dispose of an HTTPClient created from HTTPClient factory, I don't think it matters that much. But other than that, you don't want to HTTPClient is one of those resources that implements I disposable, that you'd actually most of the time do not want to dispose 99% of the time.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops