HttpClient - classe di configurazione rapida
25 giugno 2025
IIS | Asp.net core 8 I MVC | C#

In alcune circostanze (generalmente quando non si prevedano tempi di latenza eccessivamente lunghi) l'interrogazione di un servizio web può essere effettuata direttamente all'interno della action del controller tramite la classe HttpClient (System.Net.HttpClient). HttpClient implementa il processo di comunicazione http e viene configurata tramite la classe HttpRequestMessage (System.Net.HttpRequestMessage) mentre la risposta è rappresentata dalla classe HttpResponseMessage (System.Net.HttpResponseMessage). Per rendere più comoda e compatta l'interrogazione di un servizio locale o cross domain tramite HttpClient abbiamo deciso di realizzare una semplice classe facilmente estendibile e in grado di nasconderne la complessità. Per comprendere la logica sottostante l'inizializzazione della nostra classe è necessario spendere alcune parole sul ruolo dei cookie nelle chiamate locali e cross domain. Per motivi di sicurezza i cookie, generati dal web server e inseriti all'interno dell'intestazione della pagina web inviata al client, non dovrebbero mai essere trasmessi in una chiamata cross domain (di fatto i browser non lo fanno). HttpClient di default non inserisce cookie nell'intestazione della pagina ma è possibile farlo a prescindere che la chiamata sia diretta a un servizio locale o remoto. In fase di inizializzazione della nostra classe distinguiamo le chiamate locali da quelle cross domain inserendo i cookie solo all'interno delle intestazioni di quelle locali.


using System.Net;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;

namespace [projectname].HttpClientScaffold
{
    public class HttpClientScaffold
    {
        public HttpClientScaffold(HttpRequest Request, HttpMethod Method, string uri, Object? content, string? Token = null
        {
            switch (uri.StartsWith("/"))
            {
                case true: // local domain service
                    request = new HttpRequestMessage(Method, $"{Request.Scheme}://{Request.Host}{Request.PathBase}" + uri);
                    //In this case it is necessary manually add cookies into the http header (only browsers do it)
                    var cookieContainer = new CookieContainer();
                    var handler = new HttpClientHandler() { CookieContainer = cookieContainer };
                    client = new HttpClient(handler);
                  if (request.RequestUri != null)                   
                    foreach (var c in Request.Cookies) // Loading cookies
                    {
                        cookieContainer.Add(new Uri(request.RequestUri.ToString(), new Cookie(c.Key, c.Value));
                    }
                    break;
                case false: // Cross Domain Service
                    client = new HttpClient();
                    request = new HttpRequestMessage(Method, uri);
                    if (!String.IsNullOrEmpty(Token)) request.Headers.Add("Authorization", Token);
                    request.Headers.Add("Accept-Language", Thread.CurrentThread.CurrentUICulture.ToString());
                    break;
            }
            if (content != null
            {
                request.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8);
                request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
        }
        private HttpClient client;
        private HttpRequestMessage request;
        private HttpResponseMessage? response;
        public string JsonResult { get; private set; } = string.Empty;
        private async Task _SendAsync()
        {
            response = await client.SendAsync(request);
        }
        public void SendAsync()
        {
            _SendAsync().Wait();
        }
        public bool IsSuccessStatusCode() 
        { 
            if (response == null) return false;
            return response.IsSuccessStatusCode;
        }
        public HttpStatusCode StatusCode()
        {
            if (response == null) return 0;
            return response.StatusCode;
        }
        private async Task _ReadAsStringAsync()
        {
            if (response != null)
            {
                JsonResult = await response.Content.ReadAsStringAsync();
            }
        }
        public void ReadAsStringAsync()
        {
            _ReadAsStringAsync().Wait();
        }
    }
}


Esempio       

public AssignedPolicies GetAssignedPolicies(HttpRequest Request, IConfiguration configuration, int userID, string? Token = null)
        {
            AssignedPolicies? result = null;
            try
            {
                string? uri = configuration.GetSection("Endpoint")[AssignedPoliciesKey];

                if (string.IsNullOrEmpty(uri)) throw new Exception();

                uri = uri + "?userId=" + userID.ToString();

                HttpClientScaffold.HttpClientScaffold client = new HttpClientScaffold.HttpClientScaffold(Request, HttpMethod.Get, uri, null, Token);

                client.SendAsync();

                if (client.IsSuccessStatusCode())
                {
                    client.ReadAsStringAsync();
                    result = Newtonsoft.Json.JsonConvert.DeserializeObject<AssignedPolicies>(client.JsonResult);
                    if (result == null) result = new AssignedPolicies(StatusCodes.Status500InternalServerError, "", "GetAssignedPolicies");
                }
                else
                {
                    result = new AssignedPolicies((int)client.StatusCode(), "", "GetAssignedPolicies");
                }
                return result;
            }
            catch (Exception e) { return new AssignedPolicies(StatusCodes.Status500InternalServerError, e.Message, "GetAssignedPolicies"); }
        }

Torna all'inizio