/// <summary>
 /// Performs an asynchronous GET request to the Dinero API.
 /// </summary>
 /// <param name="dinero">An instance of the Dinero class. This is needed since it know about the user, the app and their credentials.</param>
 /// <param name="baseUri">The base URI to Dineo API. This is the URL without the path, but only the domain and API version.</param>
 /// <param name="requestParameters">Parameters to be used for generating the URL. Should contain the endpoint and any needed query parameters.</param>
 /// <param name="callback">Action to be called with the result from the API.</param>
 public static void PerformGetAsync(Dinero dinero, Uri baseUri, Dictionary<string, string> requestParameters,
     Action<DineroResult<string>> callback)
 {
     const string method = "GET";
     var url = BuildUri(dinero, baseUri, requestParameters).AbsoluteUri;
     DownloadDataAsync(dinero, method, url, callback);
 }
        /// <summary>
        /// Builds the URI to be used for the Dinero request.
        /// </summary>
        /// <param name="dinero">An instance of the Dinero class. This is needed since it know about the user, the app and their credentials.</param>
        /// <param name="baseUri">The base URI to Dineo API. This is the URL without the path, but only the domain and API version.</param>
        /// <param name="requestParameters">Parameters to be used for generating the URL. Should contain the endpoint and any needed query parameters.</param>
        /// <returns></returns>
        public static Uri BuildUri(Dinero dinero, Uri baseUri, Dictionary<string, string> requestParameters)
        {
            string endpoint = requestParameters["endpoint"];
            if (RequiresOrganizationId.Any(e => endpoint.IndexOf(e, StringComparison.Ordinal) >= 0))
            {
                endpoint = dinero.OrganizationId + "/" + endpoint;
            }

            // Build the query part of the URL.
            string uri = endpoint + "/?";
            foreach (KeyValuePair<string, string> keyValuePair in requestParameters)
            {
                // Skip the end point since that isn't a query parameter
                if (keyValuePair.Key == DineroApiParameterName.Endpoint) continue;
                // Skip the post body since that isn't a query parameter
                if (keyValuePair.Key == DineroApiParameterName.PostBody) continue;
                uri = uri + string.Format(
                    "{0}={1}&",
                    keyValuePair.Key, Uri.EscapeDataString(keyValuePair.Value ?? string.Empty));
            }

            // Removed not needed ending characters.
            if (uri[uri.Length - 1] == '&')
            {
                uri = uri.Remove(uri.Length - 1);
            }

            if (uri[uri.Length - 1] == '?')
            {
                uri = uri.Remove(uri.Length - 1);
            }

            return new Uri(baseUri, new Uri(uri, UriKind.Relative));
        }
 private static void SetUpDinero()
 {
     _dinero = new Dinero(ClientId, ClientSecret, ApiKey, OrganizationId);
 }
 /// <summary>
 /// Performs an asynchronous POST request to the Dinero API.
 /// </summary>
 /// <param name="dinero">An instance of the Dinero class. This is needed since it know about the user, the app and their credentials.</param>
 /// <param name="baseUri">The base URI to Dineo API. This is the URL without the path, but only the domain and API version.</param>
 /// <param name="requestParameters">Parameters to be used for generating the URL. Should contain the endpoint, the post body and any needed query parameters.</param>
 /// <param name="callback">Action to be called with the result from the API.</param>
 public static void PerformPostAsync(Dinero dinero, Uri baseUri, Dictionary<string, string> requestParameters,
     Action<DineroResult<string>> callback)
 {
     const string method = "POST";
     var url = BuildUri(dinero, baseUri, requestParameters).AbsoluteUri;
     UploadDataAsync(dinero, method, url, requestParameters[DineroApiParameterName.PostBody], callback);
 }
        /// <summary>
        /// Uploads data to the API.
        /// </summary>
        /// <param name="dinero">An instance of the Dinero class. This is needed since it know about the user, the app and their credentials.</param>
        /// <param name="method">Method to use for the request. Currently just POST.</param>
        /// <param name="url">URL to dupload the data to.</param>
        /// <param name="data">Data to upload. Should be a JSON string.</param>
        /// <param name="callback">Actin to call when the data has been uploaded and the server has returned.</param>
        private static void UploadDataAsync(Dinero dinero, string method, string url, string data, Action<DineroResult<string>> callback)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.SetBearerToken(dinero.GetRequestToken());
                if (method == "POST")
                {
                    var stringContent = new StringContent(data, Encoding.UTF8, "application/json");
                    var r = httpClient.PostAsync(new Uri(url), stringContent).Result;
                    var local = new DineroResult<string>();
                    if (r.IsSuccessStatusCode)
                    {
                        local.Result = r.Content.ReadAsStringAsync().Result;
                    }
                    else
                    {
                        local.HasError = true;
                        local.ErrorMessage = r.Content.ReadAsStringAsync().Result;
                    }

                    callback(local);
                }
            }
        }
        /// <summary>
        /// Download data from the API.
        /// </summary>
        /// <param name="dinero">An instance of the Dinero class. This is needed since it know about the user, the app and their credentials.</param>
        /// <param name="method">Method to be used for the request. Currently just GET.</param>
        /// <param name="url">URL to download the data from.</param>
        /// <param name="callback">Action to call when data has downloaded.</param>
        private static void DownloadDataAsync(Dinero dinero, string method, string url, Action<DineroResult<string>> callback)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.SetBearerToken(dinero.GetRequestToken());
                if (method == "GET")
                {
                    var r = httpClient.GetAsync(new Uri(url)).Result;

                    var local = new DineroResult<string>();
                    if (r.IsSuccessStatusCode)
                    {
                        local.Result = r.Content.ReadAsStringAsync().Result;
                    }
                    else
                    {
                        local.HasError = true;
                        local.ErrorMessage = r.Content.ReadAsStringAsync().Result;
                    }

                    callback(local);
                }
            }
        }