Search code examples
c#.netresthttpclientdotnet-httpclient

Loop skips iteration after http request


I can't figure out why this simple console (.Net Framework 4.5) app skips some iterations. As you can see in the code below i loop through the List of Fornitori and for each one of it i execute a post http request. If i have 1200 fornitori i expect 1200 requests but from the logs i get only 300. The strange thing is that i don't get any exception and i await the async method PostFornitoreAsync. I've tried to build a mock API myself and calling that instead the one i have to call and everything works but i can not figure out why the iterations are skipped even if there is some problem on the API side.



namespace Demoni___FornitoriPLM
{
    internal class Program
    {
        static IFornitoriRepository fornitoriRepository = new FornitoriRepository();
        static HttpClient httpClient = new HttpClient();
        const string fileName = "lastRun_FornitoriPLM.txt";
        static async Task Main(string[] args)
        {
            StringBuilder log = new StringBuilder("Fornitori elaborati:\n");
            try
            {
                httpClient.Timeout = TimeSpan.FromSeconds(60);
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                httpClient.BaseAddress = new Uri(ConfigurationManager.AppSettings["Uri"]);
                httpClient.DefaultRequestHeaders.Accept.Clear();
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                httpClient.DefaultRequestHeaders.Add("client_id", ConfigurationManager.AppSettings["ClientId"]);
                httpClient.DefaultRequestHeaders.Add("client_secret", ConfigurationManager.AppSettings["ClientSecret"]);

                //Aggiorno i fornitori dall'ultima volta che è girato il demone.
                string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "lasportiva", fileName);
                DateTime lastRun = new DateTime();
                if (File.Exists(filePath))
                    lastRun = Convert.ToDateTime(File.ReadAllText(filePath));

                var fornitori = await fornitoriRepository.GetFornitoriAsync(lastRun);
                int contatoreLog = 1;
                foreach (var fornitore in fornitori)
                {
                    string logFornitore = $"{contatoreLog} chiamata - id fornitore (erpcode): {fornitore.Id}";
                    Console.WriteLine(logFornitore);
                    log.AppendLine(logFornitore);

                    FornitoreDTO fornitoreDaCreare = new FornitoreDTO
                    {
                       //here i map the fields
                    };

                    string logInizio = $"Inizio chiamata {contatoreLog}: {DateTime.Now}";
                    Console.WriteLine(logInizio);
                    log.AppendLine(logInizio);
                    string messaggioErrore = await PostFornitoreAsync(fornitoreDaCreare);
                    string logFine = $"Fine chiamata {contatoreLog}: {DateTime.Now}";
                    Console.WriteLine(logFine);
                    log.AppendLine(logFine);
                    if (messaggioErrore == null)
                    {
                        string logEsito = $"- {fornitoreDaCreare.erpcode} OK \n--------------------------------------------------------------------------------------";
                        Console.WriteLine(logEsito);
                        log.AppendLine(logEsito);
                    }
                    else
                    {
                        string logEsito = $"- {fornitoreDaCreare.erpcode} ERRORE:\n{messaggioErrore} \n--------------------------------------------------------------------------------------";
                        Console.WriteLine(logEsito);
                        log.AppendLine(logEsito);
                    }

                    contatoreLog++;
                }

                File.WriteAllText(filePath, DateTime.Now.ToString());
            }
            catch(Exception ex)
            {
                Log.InvioLog("Errore Demoni - FornitoriPLM", ex.ToString());
                Console.WriteLine($"ECCEZIONE: {ex}");
            }
            finally
            {
                Log.InvioLog("Demoni - FornitoriPLM", log.ToString());
            }
        }

        /// <summary>
        /// Se la richiesta POST è andata a buon fine ritorna null, altrimenti il messaggio d'errore
        /// </summary>
        /// <param name="fornitore">Fornitore da esportare.</param>
        private static async Task<string> PostFornitoreAsync(FornitoreDTO fornitore)
        {
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, ConfigurationManager.AppSettings["ResourceUri"]);
            string body = JsonConvert.SerializeObject(fornitore);
            request.Content = new StringContent(body, Encoding.UTF8, "application/json");

            //Questo andrebbe usato solo in dev ma tanto sul server la connessione è in vpn e con whitelist
            //System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
            HttpResponseMessage response = await httpClient.SendAsync(request);
            Console.WriteLine($"STATUS CODE: {response.StatusCode}");
            if (!response.IsSuccessStatusCode)
            {
                string bodyResponse = await response.Content.ReadAsStringAsync();
                string messaggioErrore = $"Body Richiesta:\n{body}" +
                                  $"\n\nStatus Code Risposta: {response.StatusCode}\n\nBody Risposta:\n{bodyResponse}";
                return messaggioErrore;
            }

            Console.WriteLine($"{response.StatusCode} {await response.Content.ReadAsStringAsync()}");
            return null;
        }
    }
}


Solution

  • The issue proved to be more straightforward than initially anticipated. It was discovered that in the development environment, the "lastRun" date differed from that in the production environment, despite the initial assumption of their equivalence. Consequently, the elements within the "fornitori" list turned out to be different. I've made the wrong assumption that some elements of "fornitori" were skipped.