public async Task <IEXResponse <ReturnType> > SymbolsExecuteAsync <ReturnType>(string urlPattern, IEnumerable <string> symbols)
            where ReturnType : class
        {
            var qsb = new QueryStringBuilder();

            qsb.Add("symbols", string.Join(",", symbols));

            var pathNvc = new NameValueCollection();

            return(await ExecuteAsync <ReturnType>(urlPattern, pathNvc, qsb).ConfigureAwait(false));
        }
Beispiel #2
0
        public SSEClient <T> SymbolsSubscribeSSE <T>(string urlPattern, IEnumerable <string> symbols, bool forceUseSecretToken = false)
            where T : class
        {
            var qsb = new QueryStringBuilder();

            if (!string.IsNullOrEmpty(publishableToken) && !forceUseSecretToken)
            {
                qsb.Add("token", publishableToken);
            }

            if (!string.IsNullOrEmpty(secretToken) && forceUseSecretToken)
            {
                qsb.Add("token", secretToken);
            }

            qsb.Add("symbols", string.Join(",", symbols));

            var pathNvc = new NameValueCollection();

            return(SubscribeToSSE <T>(urlPattern, pathNvc, qsb));
        }
        public async Task <IEXResponse <ReturnType> > ExecuteAsync <ReturnType>(
            string urlPattern, NameValueCollection pathNVC, QueryStringBuilder qsb, bool forceUseSecretToken = false)
        {
            ValidateAndProcessParams(ref urlPattern, ref pathNVC, ref qsb);

            if (!string.IsNullOrEmpty(publishableToken) && !forceUseSecretToken)
            {
                qsb.Add("token", publishableToken);
            }

            if (!string.IsNullOrEmpty(secretToken) && forceUseSecretToken)
            {
                qsb.Add("token", secretToken);
            }

            if (sign)
            {
                client.DefaultRequestHeaders.Remove("x-iex-date");
                client.DefaultRequestHeaders.Remove("Authorization");

                (string iexdate, string authorization_header)headers = signer.Sign(publishableToken, "GET", urlPattern, qsb.Build());
                client.DefaultRequestHeaders.TryAddWithoutValidation("x-iex-date", headers.iexdate);
                client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", headers.authorization_header);
            }

            using (var responseContent = await backOffPolicy.ExecuteAsync(() => client.GetAsync($"{urlPattern}{qsb.Build()}")))
            {
                var content = string.Empty;
                try
                {
                    content = await responseContent.Content.ReadAsStringAsync();

                    if (responseContent.StatusCode == HttpStatusCode.OK)
                    {
                        Debug.WriteLine("Successful Request");
                        // Successful Request
                        // The logic that follows is included to handle the edge case of pulling
                        // dividend or split information in the cases where the DividendRange or
                        // SplitRange are set to "Next". When dividends and splits do not exist,
                        // the IEXCloud API returns an empty array for all other types of
                        // DividendRange and SplitRange values, but in the case of "Next", it
                        // returns an empty object (i.e., "{}"). As such, this case must be handled
                        // separately without breaking existing functionality.
                        if (typeof(IEnumerable).IsAssignableFrom(typeof(ReturnType))
                            // Must exclude desired return types of string from this conditional because
                            // strings are also assignable from IEnumerable (i.e., IEnumerable<char>)
                            && typeof(ReturnType) != typeof(string)
                            // Dictionaries will also be assignable from IEnumerable but it is expected
                            // that their JSON representation would begin with "{" instead of "["
                            && !typeof(IDictionary).IsAssignableFrom(typeof(ReturnType)) &&
                            content[0] != '[')
                        {                         // if expecting an array but receive a single item instead, create a new List with that single item
                            content = '[' + content + ']';
                        }
                        return(new IEXResponse <ReturnType>()
                        {
                            Data = JsonSerializer.Deserialize <ReturnType>(content, JsonSerializerOptions)
                        });
                    }
                    else
                    {                     // Failed Request
                        return(new IEXResponse <ReturnType> {
                            ErrorMessage = $"{responseContent.StatusCode} - {content}"
                        });
                    }
                }
                catch (JsonException ex)
                {
                    throw new JsonException(content, ex);
                }
            }
        }
Beispiel #4
0
        protected static void ValidateAndProcessParams(ref string urlPattern, ref NameValueCollection pathNVC, ref QueryStringBuilder qsb)
        {
            if (string.IsNullOrWhiteSpace(urlPattern))
            {
                throw new ArgumentException("urlPattern cannot be null");
            }
            else if (pathNVC == null)
            {
                throw new ArgumentException("pathNVC cannot be null");
            }
            qsb = qsb ?? new QueryStringBuilder();

            if (pathNVC.Count > 0)
            {
                foreach (string key in pathNVC.Keys)
                {
                    if (string.IsNullOrWhiteSpace(key))
                    {
                        throw new ArgumentException("pathNVC cannot be null");
                    }
                    else if (string.IsNullOrWhiteSpace(pathNVC[key]))
                    {
                        throw new ArgumentException($"pathNVC {key} value cannot be null");
                    }
                    else if (urlPattern.IndexOf($"[{key}]") < 0)
                    {
                        throw new ArgumentException($"urlPattern doesn't contain key [{key}]");
                    }
                    else
                    {
                        urlPattern = urlPattern.Replace($"[{key}]", pathNVC[key]);
                    }
                }
            }
        }
Beispiel #5
0
        public SSEClient <T> SubscribeToSSE <T>(string urlPattern, NameValueCollection pathNVC, QueryStringBuilder qsb)
        {
            ValidateAndProcessParams(ref urlPattern, ref pathNVC, ref qsb);
            var url = $"{baseSSEURL}{urlPattern}{qsb.Build()}";

            return(new SSEClient <T>(Configuration.Builder(new Uri(url)).Build()));
        }