Search code examples
c#postmandotnet-httpclient

Data retrieved from API using Postman different than when using C# program


Data which I retrieved from a sigfox API using postman is different than the data which I got when using C# program using http client.

The API contains query parameters such as:

  • limit=(a number) -- number which limits the number of messages I can receive (doesn't affect the problem)

and

  • before = (unix time)
  • since= (unix time) which is the time parameters.

In postman, the data I received follows the time parameter meaning data received is before set timing and since set timing.

Api link(with fake info): https://backend.sigfox.com/api/devicetypes/devicetpes-id(filler)/messages?limit=100&before=1568186400&since=1568185800

This is for the download section of the data:

public static class DownloadData
{
    private static string UrlParameters="?limit=100&before=&since=";
    public static void GetfromAPI(string deviceId, long beforeTime, long sinceTime)
    {
        var apiResponse = new Models.Datas();
        var baseUrl = ConfigurationManager.AppSettings["ApiBaseUrl"];
        var username = ConfigurationManager.AppSettings["ApiUserName"];
        var password = ConfigurationManager.AppSettings["ApiPassword"];
        var mediatype = ConfigurationManager.AppSettings["MediaType"];
        var finalUrl = string.Format(baseUrl, deviceId, beforeTime, sinceTime);
        using (var client = new ApiClient(finalUrl, username, password, mediatype))
        {
            //apiResponse = client.GetAsyncMessage<Models.Datas>(UrlParameters).Result;
            apiResponse = client.GetAsyncMessage<Models.Datas>(UrlParameters).Result;
            InsertToDatabase(FormatData(apiResponse.Data)); //apiresponse.data is holding the data

        }
    }

http client

public class ApiClient : IDisposable
{
    private HttpClient _httpClient;
    private readonly string _baseurl;
    private readonly string _username;
    private readonly string _password;
    private readonly string _mediatype;


    public ApiClient(string baseurl, string username, string password , string mediatype)
    {
        _baseurl = baseurl;
        _username = username;
        _password = password;
        _mediatype = mediatype;
    }

    public async Task<TResult> GetAsyncMessage<TResult>(string url) where TResult : class, new()

    {
        var strResponse = await GetAsyncMessage(url);



        return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings ///str respons holding the string 
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    private async Task<string> GetAsyncMessage(string url)
    {
        CheckHttpClientConnection();

        using (var response = await _httpClient.GetAsync(url))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();


        }
    }

httpclientwith basic auth

private void CreateHttpClient()
    {
        _httpClient = new HttpClient { BaseAddress = new Uri(_baseurl) };
        byte[] cred = UTF8Encoding.UTF8.GetBytes(_username + ":" + _password);
        _httpClient.DefaultRequestHeaders.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
        _httpClient.DefaultRequestHeaders.Accept.Add(
            new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(_mediatype));
    }

a FUNCTION in another file which runs the top code

DownloadData.GetfromAPI("devicetypesid filler",Common.BCurrenttimetoUnix(), Common.SCurrenttimetoUnix());

the common.bcurrentimetounix etc is taking the value from the function as the before and since query parameters.

So data i got in postman follows the query parameter. meaning that data i got is in the before and since timing span.

example:

before :4.50pm since 4.40pm is the timing set for params.

Data retrieved is 1st data = 4.49pm, 100th data= 4.41pm.

However in my C# program it does not even follow the parameter. data retrieved exceed both since and before timing.

EDIT #1. Images

EDIT #2

BASEURL :

<add key="ApiBaseUrl" value="https://api.sigfox.com/v2/device-types/{0}/messages" />

Edit #3

Working with this as baseurl: Debugging screenshots :

  <add key="ApiBaseUrl"  value="https://api.sigfox.com/v2/device-types/{0}/messages?limit=100&amp;before={1}&amp;since={2}" />

Edit #4

This code is working.


        public static void GetfromAPI(string deviceId, long beforeTime, long sinceTime)
        {
            var apiResponse = new Models.Datas();
            var baseUrl = ConfigurationManager.AppSettings["ApiBaseUrl"];
            var username = ConfigurationManager.AppSettings["ApiUserName"];
            var password = ConfigurationManager.AppSettings["ApiPassword"];
            var mediatype = ConfigurationManager.AppSettings["MediaType"];
            var urlparam = ConfigurationManager.AppSettings["ApiParam"];
                
            var finalurl = string.Format(baseUrl, deviceId);
            var urlParam = $"?limit=100&before={beforeTime}&since={sinceTime}";

            using (var client = new ApiClient(finalurl, username, password, mediatype))
            {
                //apiResponse = client.GetAsyncMessage<Models.Datas>(UrlParameters).Result;
                apiResponse = client.GetAsyncMessage<Models.Datas>(urlParam).Result;
                InsertToDatabase(FormatData(apiResponse.Data)); //apiresponse.data is holding the data

            }

Solution

  • You are setting your UrlParameters variable without values for before or since:-

    private static string UrlParameters="?limit=100&before=&since=";
    

    And you are not updating that before you send it; where you set finalUrl, your string.Format doesn't reference UrlParameters; hence you are gettings values outside your specified beforeTime and afterTime.

    It's not clear what ApiClient you are using, however, here is an example using the basic WebClient:-

    var baseUrl = "https://backend.sigfox.com/api/devicetypes";
    var deviceId = "12345";
    var before = 1568186400;
    var since = 1568185800;
    
    var url = $@"{baseUrl}/{deviceId}/messages?limit=100&before={before}&since={since}";
    
    var json = new System.Net.WebClient().DownloadString(url);
    

    EDIT

    Try updating your GetfromAPI method like this (I've fixed how finalUrl is constructed, and pass it, instead of UrlParameters to your GetAsyncMessage method and I pass baseUrl instead of finalUrl to your ApiClient constructor):-

    public static class DownloadData
    {
        public static void GetfromAPI(string deviceId, long beforeTime, long sinceTime)
        {
            var apiResponse = new Models.Datas();
            var baseUrl = ConfigurationManager.AppSettings["ApiBaseUrl"];
            var username = ConfigurationManager.AppSettings["ApiUserName"];
            var password = ConfigurationManager.AppSettings["ApiPassword"];
            var mediatype = ConfigurationManager.AppSettings["MediaType"];
    
            var finalUrl = $"api/devicetypes/{deviceId}/messages?limit=100&before={beforeTime}&since={sinceTime}";
    
            using (var client = new ApiClient(baseUrl, username, password, mediatype))
            {
                apiResponse = client.GetAsyncMessage<Models.Datas>(finalUrl).Result;
                InsertToDatabase(FormatData(apiResponse.Data)); //apiresponse.data is holding the data
            }
        }
    }
    

    NOTE: You may need to fiddle with finalUrl depending on what your baseUrl is set to (I can't see that here); the idea is to check that url value just before you pass it to HttpClient so you can confirm what it's trying to fetch.