Many Ways to make and Deserialize an HTTP GET with HttpClient
While playing around with source generation for System.Text.Json, I realized that over the years I have made HTTP GET requests and the subsequent deserialization of the response in many ways. I thought it would be fun to show some of the different ways to do this.
The sample code below makes requests to https://jsonplaceholder.typicode.com
, a “free fake API for testing and prototyping”.
Create a new application and add the Microsoft.AspNet.WebApi.Client
package (this will let you use ReadAsAsync<T>
).
Replace the code in Program.cs
, with the below, there are some inline notes -
1using System.Net.Http.Json;
2using System.Text.Json;
3
4HttpClient httpClient = new HttpClient()
5{
6 BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
7};
8
9var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
10MyJsonContext myJsonContext = new MyJsonContext(options);
11
12Console.WriteLine("1. GetAsync and ReadFromJsonAsync, with source generation");
13var httpResponseMessage1 = await httpClient.GetAsync("users/1");
14httpResponseMessage1.EnsureSuccessStatusCode();
15var user1 = await httpResponseMessage1.Content.ReadFromJsonAsync(myJsonContext.User);
16Console.WriteLine($"{user1}\n");
17
18
19Console.WriteLine("2. GetAsync and ReadFromJsonAsync");
20var httpResponseMessage2 = await httpClient.GetAsync("users/2");
21httpResponseMessage2.EnsureSuccessStatusCode();
22var user2 = await httpResponseMessage2.Content.ReadFromJsonAsync<User>();
23Console.WriteLine($"{user2}\n");
24
25
26Console.WriteLine("3. GetAsync, ReadAsStringAsync, and JsonSerializer, with source generation");
27var httpResponseMessage3 = await httpClient.GetAsync("users/3");
28httpResponseMessage3.EnsureSuccessStatusCode();
29var user3String = await httpResponseMessage3.Content.ReadAsStringAsync();
30var user3 = JsonSerializer.Deserialize(user3String, myJsonContext.User);
31Console.WriteLine($"{user3}\n");
32
33
34Console.WriteLine("4. GetAsync, ReadAsStringAsync, and JsonSerializer");
35var httpResponseMessage4 = await httpClient.GetAsync("users/4");
36httpResponseMessage4.EnsureSuccessStatusCode();
37var user4String = await httpResponseMessage4.Content.ReadAsStringAsync();
38var user4 = JsonSerializer.Deserialize<User>(user4String, options);
39Console.WriteLine($"{user4}\n");
40
41
42Console.WriteLine("5. GetFromJsonAsync");
43var user5 = await httpClient.GetFromJsonAsync<User> ("users/5");
44Console.WriteLine($"{user5}\n");
45
46
47Console.WriteLine("6. GetFromJsonAsync with source generation");
48var user6 = await httpClient.GetFromJsonAsync("users/6", myJsonContext.User);
49Console.WriteLine($"{user6}\n");
50
51
52Console.WriteLine("7. GetAsync and ReadAsAsync<User>");
53var httpResponseMessage7 = await httpClient.GetAsync("users/7");
54httpResponseMessage7.EnsureSuccessStatusCode();
55var user7 = await httpResponseMessage7.Content.ReadAsAsync<User>();
56Console.WriteLine($"{user7}\n");
57
58
59Console.WriteLine("8. GetStringAsync and JsonSerializer.Deserialize");
60var user8String = await httpClient.GetStringAsync("users/8");
61var user8 = JsonSerializer.Deserialize<User>(user8String, options);
62Console.WriteLine($"{user8}\n");
63
64
65Console.WriteLine("9. GetStringAsync and JsonSerializer.Deserialize, with source generation");
66var user9String = await httpClient.GetStringAsync("users/9");
67var user9 = JsonSerializer.Deserialize(user9String, myJsonContext.User);
68Console.WriteLine($"{user9}\n");
69
70
71Console.WriteLine("10. GetStreamAsync and JsonSerializer.Deserialize");
72var user10Stream = await httpClient.GetStreamAsync("users/10");
73var user10 = JsonSerializer.Deserialize<User>(user10Stream, options);
74Console.WriteLine($"{user10}\n");
75
76
77Console.WriteLine("11. GetAsync and GetStreamAsync, with source generation");
78var user11Stream = await httpClient.GetStreamAsync("users/10");
79var user11 = JsonSerializer.Deserialize(user11Stream, myJsonContext.User);
80Console.WriteLine($"{user11}\n");
I stopped at 11 because I was a little tired of doing it, but there are a few more ways.
Add a User
class to the project. This is the type the JSON responses will be deserialized to.
Note on lines 3-4, I setup source generation for the User
type.
1using System.Text.Json.Serialization;
2
3[JsonSerializable(typeof(User))]
4internal partial class MyJsonContext : JsonSerializerContext {}
5
6public class User
7{
8 public override string ToString()
9 {
10 return $"Name: {Name}, Phone: {Phone}";
11 }
12
13 public int Id { get; set; }
14 public string Name { get; set; }
15 public string Username { get; set; }
16 public string Email { get; set; }
17 public Address Address { get; set; }
18 public string Phone { get; set; }
19 public string Website { get; set; }
20 public Company Company { get; set; }
21}
22
23public class Address
24{
25 public string Street { get; set; }
26 public string Suite { get; set; }
27 public string City { get; set; }
28 public string Zipcode { get; set; }
29 public Geo Geo { get; set; }
30}
31
32public class Company
33{
34 public string Name { get; set; }
35 public string CatchPhrase { get; set; }
36 public string Bs { get; set; }
37}
38
39public class Geo
40{
41 public string Lat { get; set; }
42 public string Lng { get; set; }
43}