Connect to API fails with C#

I have tried various C# codes approaches for connecting to an API but cannot so far get it to work. The url works every time with a Chrome browser. I have looked at many post here on stackoverflow but have not found answers the problem. In C# i have tried webclient, httpclient, no luck. With postman i get the data easily. I have tried to watch the request with Fiddler 4. The postman request works great and is easy to see but when running the C# code the request never shows up despite https traffic gets captured and decoded. Many times it is timeout or connecting was closed. I do not believe it to be a firewall issue. Here is some C# that does not work:

internal class Program
{
    static void Main(string[] args)
    {
        Getit();
    }

    private static async void Getit()
    {
        try
        {
            string baseUrl = "https://api.nasdaq.com/api/nordic/instruments/CSE32679/trades?type=INTRADAY&assetClass=SHARES&lang=en";
                            
            var client = new System.Net.Http.HttpClient();
            //var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, baseUrl);

            var request = new HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = new Uri(baseUrl),
                Headers = {
                { HttpRequestHeader.UserAgent.ToString(), "Could try to set this" },
                { HttpRequestHeader.Accept.ToString(), "application/json" },
                { HttpRequestHeader.Cookie.ToString(), "ak_bmsc=057AA34F94542D7FBF06A239807E1BC8~000000000000000000000000000000~YAAQHmjdWE1nYjiTAQAASfEPZRmj3xtTz7eQGDtn2GEgSGhkx070psq3nqpvIhA3wzaXGJm2o91q1M3D6DvQwqUZzuw+esKY13f8GdqUt4dJPxrgvfliIS8ehkC7YBSn7IH6Bcw/8s8hOjaP8i3WszFF0UMpQ4EaBthZep9yFYRYELgRMKXnMyzQBUsdAPhaoZIB9An1hH3LmRhIIx9zkwRt4TCY3O2eBOYzaHyo95pTmhp9SSWzHUM6RCj5+owjXtoHDlSjIHRmCVwtpNp20gn5b70Dvvb4C6tpdNUWvK8YJFbs6M5h+0ho0Z0SfGND59oPOaMSA5/i8wRKfiV/fl7ZtQtyQ8RQDxcMxA==; akaalb_ALB_Default=~op=ao_api_port_8085:ao_api_east2|~rv=23~m=ao_api_east2:0|~os=ff51b6e767de05e2054c5c99e232919a~id=ad3d95899a893885df1dfabdf47494ac" },
                { "X-Version", "1" }
                    },
                
            };

            var response = await client.SendAsync(request);
            response.EnsureSuccessStatusCode();
            Console.WriteLine(response.Content.ReadAsStringAsync());

        }
        catch (Exception e)
        {

        }
    }      
}

Can someone help me by showing some C# code that will do it?

The issue might be related to missing or incorrect HTTP headers, such as User-Agent, Accept, or authentication-related headers. Browsers and Postman typically include default headers and handle things like cookies and redirects seamlessly, whereas in C#, you need to explicitly provide them.

Below is a working example for making an HTTP GET request to the specified API using HttpClient in C#.


Corrected Code

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

internal class Program
{
    static async Task Main(string[] args)
    {
        await GetIt();
    }

    private static async Task GetIt()
    {
        try
        {
            string baseUrl = "https://api.nasdaq.com/api/nordic/instruments/CSE32679/trades?type=INTRADAY&assetClass=SHARES&lang=en";

            using (var client = new HttpClient())
            {
                // Set default headers
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"); // Mimic browser user agent
                client.DefaultRequestHeaders.Add("X-Version", "1"); // Custom header

                // If a cookie is required, you need to provide it
                client.DefaultRequestHeaders.Add("Cookie", "ak_bmsc=057AA34F94542D7FBF06A239807E1BC8~...");

                // Make the request
                var response = await client.GetAsync(baseUrl);

                if (response.IsSuccessStatusCode)
                {
                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}");
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Exception: {e.Message}");
        }
    }
}

Key Changes and Considerations

  1. Correct Headers:
  • The User-Agent header is required as many APIs block requests from unknown or non-browser-like clients.
  • The Accept header specifies the expected response format (JSON).
  • Cookies and custom headers (X-Version, etc.) were explicitly added as per the API requirements.
  1. Cookie Handling:
  • If the Cookie header is essential for accessing the API, include it. If you’re unsure about the exact value, check it in Postman or the browser’s developer tools (Network tab).
  1. Using HttpClient Properly:
  • Use HttpClient with using to ensure proper disposal.
  • Avoid async void for the method; use async Task instead for better error handling and debugging.
  1. Error Handling:
  • The response status code and reason phrase are displayed when a request fails to help diagnose issues.

Debugging Tips

  1. Verify Headers:
  • Compare the headers sent by your C# code and Postman using tools like Fiddler or Wireshark.
  • Ensure that any required headers (e.g., Referer, Authorization, etc.) are included in the C# request.
  1. Check Cookies:
  • Some APIs rely on session cookies. Ensure the cookie value is valid and up-to-date.
  1. Disable Certificate Validation (if needed):
  • If there’s a certificate issue, you can bypass it during testing (not recommended in production):
HttpClientHandler handler = new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true
};
using var client = new HttpClient(handler);
  1. Inspect Response:
  • Use the response.Content.ReadAsStringAsync() to log the exact error message.

If it still doesn’t work, the issue might be related to:

  • API restrictions (e.g., rate-limiting or IP blocking).
  • Required headers or tokens (refer to the API documentation or network capture in Postman).