NET5: System.Net.Http.Json & ReadFromJsonAsync

NET5: System.Net.Http.Json & ReadFromJsonAsync

Una delle novita’ di NET5 che ho sperimentato subito e’ stato ReadFromJsonAsync presente all’interno di System.Net.Http.Json. Se vi ricordate il mio ultimo post System.Text.Json & DeserializeAsync ho mostrato una mia classe HttpClientHelper. A distanza di pochi giorni vi mostrero’ come ho modificato il tutto per migrarla alle nuove funzionalita’ di NET5.

HttpClientHelper

La classe HttpClientHelper e’ molto semplice e contiene (al momento) solamente due tipologie di Get

  • public async Task<IEnumerable> GetIEnumerableAsync(string url)
  • public async Task GetAsync(string url)

Inutile spiegarvi la differenza del valore di ritorno. Credo che la presenza o meno della parola magica IEnumerable abbastanza significativa.

1
2
3
4
5
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

Guardando con attenzione la parte using in testa al codice noterete la presenza del nuovo System.Net.Http.Json introdotto in NET5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class HttpClientHelper : IDisposable
{
    public void Dispose()
    {
    }

    public async Task<IEnumerable<T>> GetIEnumerableAsync<T>(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                using (var response = await client.SendAsync(request))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var items = await response.Content.ReadFromJsonAsync<IEnumerable<T>>();
                        return items;
                    }
                }
            }

            return default(IEnumerable<T>);
        }

        public async Task<T> GetAsync<T>(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                using (var response = await client.SendAsync(request))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var items = await response.Content.ReadFromJsonAsync<T>();
                        return items;
                    }
                }
            }

            return default(T);
        }
}

Per ogni Get esistono due tipologie di valori di ritorno

IsSuccessStatusCodeGetIEnumerableAsyncGetAsync
trueIEnumerableT
falsedefault(IEnumerable)default(T)

In questo modo -se per qualsiasi motivo- il valore di IsSuccessStatusCode risultasse false sappiamo che valore aspettare nel chiamante.

Proprio all’interno della condizione if (response.IsSuccessStatusCode) e’ presente il cambiamento rispetto alla precedente versione precedente.

Di seguito propongo due snippet di codice che utilizzano la classe HttpClientHelper appena scritta.

GetIEnumerableAsync

1
2
3
4
5
6
7
8
public async Task<IEnumerable<CustomDTO>> GetCustomDTOsAsync()
{
    using (HttpClientHelper h = new HttpClientHelper())
    {
        var result = await h.GetIEnumerableAsync<CustomDTO>(urlAzureFunction);
        return result;
    }            
}

GetIEnumerableAsync

1
2
3
4
5
6
7
8
public async Task<CustomDTO> GetCustomDTOAsync()
{
    using (HttpClientHelper h = new HttpClientHelper())
    {
        var result = await h.GetAsync<CustomDTO>(urlAzureFunction);
        return result;
    }            
}

HttpContentJsonExtensions

Prima di chiudere il post, vi voglio mostrare il contenuto della classe HttpContentJsonExtensions dove sono presenti i ReadFromJsonAsync utilizzati nell’esempio precedente.

1
2
3
4
5
//
// Summary:
//     Contains the extension methods to read and then parse the System.Net.Http.HttpContent
//     from JSON.
public static class HttpContentJsonExtensions

Task<object?> ReadFromJsonAsync

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//
// Summary:
//     Read the HTTP content and return the value resulting from deserialize the content
//     as JSON in an asynchronous operation.
//
// Parameters:
//   content:
//     The content to read from.
//
//   type:
//     The type of the object to deserialize to and return.
//
//   options:
//     Options to control the behavior during deserialization, the default options are
//     System.Text.Json.JsonSerializerDefaults.Web.
//
//   cancellationToken:
//     A cancellation token that can be used by other objects or threads to receive
//     notice of cancellation.
//
// Returns:
//     The task object representing the asynchronous operation.
public static Task<object?> ReadFromJsonAsync(this HttpContent content, Type type, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default);

Task<T?> ReadFromJsonAsync

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//
// Summary:
//     Read the HTTP content and return the value resulting from deserialize the content
//     as JSON in an asynchronous operation.
//
// Parameters:
//   content:
//     The content to read from.
//
//   options:
//     Options to control the behavior during deserialization, the default options are
//     System.Text.Json.JsonSerializerDefaults.Web.
//
//   cancellationToken:
//     A cancellation token that can be used by other objects or threads to receive
//     notice of cancellation.
//
// Type parameters:
//   T:
//     The target type to deserialize to.
//
// Returns:
//     The task object representing the asynchronous operation.
public static Task<T?> ReadFromJsonAsync<T>(this HttpContent content, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default);

Youtube

NET5: System.Net.Http.Json &amp; ReadFromJsonAsync

Nota finale

Se utilizzi NETCore ti consiglio di guardare il mio precedente articolo per ottenere lo stesso risultato System.Text.Json & DeserializeAsync