2

I've been trying to use HttpClient, to connect to an API. I'm able to send a GET request and recieve the desired data that I want from it through Postman and Fiddler, without issue.

The issue is that the json file i get from the HttpClient is: []

The HttpClient gives me the Status 200 while providing me with an empty array.

    public class CoolModel
    {
         public string name { get; set; }
         public int itemId{ get; set; }
         public string Devicename{ get; set; }
    }

var username = _config["Username"];
var password = _config[":Password"];
var encoded = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", username, password)));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encoded);
httpClient.DefaultRequestHeaders.Add("ApiKey", _config["ApiKey"]);
httpClient.DefaultRequestHeaders.Add("Accept", "*/*");
httpClient.DefaultRequestHeaders.Add("User-Agent", "C# App");

HttpResponseMessage httpResponse = httpClient.GetAsync(_config["Url"] + $"item?ID={_config["ItemId"]}&DeviceName={_config["DeviceName"]}").Result;
       
var json = await httpResponse.Content.ReadAsStringAsync();
var content = JsonConvert.DeserializeObject<List<CoolModel>>(json);

This will return the following: []

While what I want is:

[
    {
        "name":"John",
        "itemId":30,
        "Devicename":"something"
    }
]

My json that is returned is also []

  • Does the `List` type match with the returned response (pattern)? Did you try to debug to see what is the `json` value? – Yong Shun May 18 '22 at 23:50
  • Maybe the members of your `CoolModel` are Field instead of Properties; nobody knows, you didn't post the model. -- Why are you awating `ReadAsStringAsync()` but not `GetAsync()` one line before? Await both; don't block (that's what `Result` does) when you have async code. – Jimi May 19 '22 at 04:13
  • Did you set a breakpoint at ·content· to see the value? And what did you return? – Qing Guo May 19 '22 at 05:08
  • @YongShun The json value is ```[]``` @QingGuo I can only assume that Content is the same – groundclutter May 19 '22 at 05:39
  • 1
    @Jimi Sorry for not saying what the model is but they're properties. – groundclutter May 19 '22 at 05:44
  • @Jimi Added the model as you asked, and the JSON I recieve is ```[]``` – groundclutter May 19 '22 at 06:12
  • @groundclutter What is about your `httpResponse` ? – Qing Guo May 19 '22 at 06:34
  • 1
    @Jimi it is just ```[]``` I get 200 from the request, but I recieve an empty json. That is before i deserialized it. It is just ```Log.Error("Json output: {0}", json); //Returns [06:32:59 ERR] Json output: [] ``` – groundclutter May 19 '22 at 06:36
  • Then move the URL you're passing to `GetAsync()` out of there, assign it to a string variable and check what the content of that string actually is. It's quite possible that you get an empty array because the query doesn't return results based on the criteria you have set. – Jimi May 19 '22 at 07:01
  • 1
    @QingGuo is there anything specific you want from it? – groundclutter May 19 '22 at 07:14
  • Try "HttpResponseMessage httpResponse = await httpClient.GetAsync(string.Empty, HttpCompletionOption.ResponseHeadersRead); " to see what you get. @groundclutter – Qing Guo May 19 '22 at 07:19
  • 1
    @Jimi ```https://MyCoolUrl.com/cool/api/item?ID=30& DeviceName=something``` Like this? It is the same as in postman and fiddler, it looks like its broken into two parts in the log – groundclutter May 19 '22 at 07:34
  • 1
    @QingGuo I get an exception when I do the ```HttpResponseMessage httpResponse = await httpClient.GetAsync(string.Empty, HttpCompletionOption.ResponseHeadersRead);``` The Exception: An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set – groundclutter May 19 '22 at 07:42
  • 1
    @Jimi I'll try to fix it, it appears that its trying to send the request with the break, I wrote it off as the log didn't have enough spaces to show the full url. – groundclutter May 19 '22 at 07:52

3 Answers3

1

Below is a demo about using HttpClient to connect to an API, you can refer to it.

    [Route("home")]
    public class HomeController : Controller
    {

        [HttpGet]
        public async Task<IActionResult> IndexAsync()
        {
            string url = $"https://localhost:7272/weatherForecast";

            HttpClientHandler httpClientHandler = new HttpClientHandler();

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;

            HttpClient httpClient = new HttpClient(httpClientHandler)
            {
                BaseAddress = new Uri(url)
            };

            httpClient.DefaultRequestHeaders.Accept.Clear();
          
            httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");

            httpClientHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

            HttpResponseMessage response = await httpClient.GetAsync(string.Empty, HttpCompletionOption.ResponseHeadersRead);

            response.EnsureSuccessStatusCode();

            var json = await response.Content.ReadAsStringAsync();

            var content = JsonConvert.DeserializeObject<List<WeatherForecast>>(json);

            return View(content);


        }

Result:

enter image description here

Qing Guo
  • 6,041
  • 1
  • 2
  • 10
1

My issue was that the Url

var url = _config["Url"] + $"item?ID={_config["ItemId"]}&DeviceName={_config["DeviceName"]}"

Contained empty new lines, so I had to remove the new lines. so I added the following to my url .Replace("\n", "").Replace("\r", ""));

HttpResponseMessage httpResponse = await httpClient.GetAsync(url.Replace("\n", "").Replace("\r", ""));```

0

Fix your model, id should be an integer

 public class CoolModel
    {
         public string name { get; set; }
         public int id { get; set; }
         public string devicename { get; set; }
    }