public async Task <IEnumerable <CryptoCurrencyDto> > GetAvailableCryptocurrencies() { // Call the external API using the product identifier as an URL parameter to string URL = "https://data.messari.io/api/v2/assets"; string urlParameters = "?fields=id,symbol,name,slug,metrics/market_data/price_usd,profile/general/overview/project_details"; HttpClient client = new HttpClient(); client.BaseAddress = new Uri(URL); // Add an Accept header for JSON format. client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); // List data response. var response = await client.GetAsync(urlParameters); if (response.IsSuccessStatusCode) { // Deserialize the response to a CryptoCurrencyDto model var cryptoCurrencies = await HttpResponseMessageExtensions.DeserializeJsonToList <CryptoCurrencyDto>(response, true); // Filter the list for BTC, ETH, USDT and XMR var filteredCryptoCurrencies = cryptoCurrencies.Where(c => c.Symbol == "BTC" || c.Symbol == "ETH" || c.Symbol == "USDT" || c.Symbol == "XMR").ToList(); client.Dispose(); return(filteredCryptoCurrencies); } else { throw new ApplicationException("Request failed to external API."); } }
public async Task <Envelope <ExchangeDto> > GetExchanges(int pageNumber = 1) { HttpClient client = new HttpClient(); // Call the external API with a paginated query and get all exchanges with fields required for the ExchangeDto model var getExhanges = "https://data.messari.io/api/v1/markets?page={pageNumber}&fields=id,exchange_name,exchange_slug,quote_asset_symbol,price_usd,last_trade_at"; client.DefaultRequestHeaders.Accept.Clear(); //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.GetAsync(getExhanges); // Deserialize the response to a list - I would advise to use the HttpResponseMessageExtensions to deserialize and flatten the response var responseFlat = await HttpResponseMessageExtensions.DeserializeJsonToList <ExchangeDto>(response, true); // Create an envelope and add the list to the envelope and return that /*var envelope = new Envelope<ExchangeDto> * { * Items = new List<ExchangeDto>(responseFlat); * * };*/ //return envelope; return(null); }
public void GetTypeResult_WhenGivenResponseWithWeatherDetailJson_ReturnWeatherDetail() { var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK) { Content = new StringContent(TestHelper.GetWeatherDetailJson()) }; using (response) { var weatherDetail = HttpResponseMessageExtensions.GetTypedResult <WeatherDetail>(response); Assert.NotNull(weatherDetail); Assert.Equal("base", weatherDetail.Base); } }
public async Task <IEnumerable <CryptoCurrencyDto> > GetAvailableCryptocurrencies() { HttpClient client = new HttpClient(); // Call the external API and get all cryptocurrencies with fields required for the CryptoCurrencyDto model var getCurrencies = "https://data.messari.io/api/v2/assets?fields=id,name,slug,symbol,metrics/market_data/price_usd,profile/general/overview/project_details"; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.GetAsync(getCurrencies); // Deserializes the response to a list - I would advise to use the HttpResponseMessageExtensions to deserialize and flatten the response. var responseFlat = await HttpResponseMessageExtensions.DeserializeJsonToList <CryptoCurrencyDto>(response, true); // Return a filtered list where only the available cryptocurrencies BitCoin (BTC), Ethereum (ETH), Tether (USDT) and Monero (XMR) are within the list return(responseFlat.Where(s => s.Symbol == "BTC" || s.Symbol == "ETH" || s.Symbol == "USDT" || s.Symbol == "XMR")); }
public async Task AddCartItem(string email, ShoppingCartItemInputModel shoppingCartItem) { var identifier = shoppingCartItem.ProductIdentifier; if (identifier.ToUpper() != "BTC" && identifier.ToUpper() != "ETH" && identifier.ToUpper() != "USDT" && identifier.ToUpper() != "XMR") { throw new ResourceNotFoundException("Invalid product identifier."); } // Call the external API using the product identifier as an URL parameter to string URL = "https://data.messari.io/api/v1/assets/" + shoppingCartItem.ProductIdentifier + "/metrics"; string urlParameters = "?fields=id,symbol,name,slug,market_data/price_usd"; HttpClient client = new HttpClient(); client.BaseAddress = new Uri(URL); // Add an Accept header for JSON format. client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json") ); // List data response. var response = await client.GetAsync(urlParameters); if (response.IsSuccessStatusCode) { // Receive the current price in USD for this particular cryptocurrency // Deserialize the response to a CryptoCurrencyDto model var responseObject = await HttpResponseMessageExtensions.DeserializeJsonToObject <CryptoCurrencyDto>(response, true); client.Dispose(); _shoppingCartRepository.AddCartItem(email, shoppingCartItem, responseObject.PriceInUsd); } else { throw new Exception("Response failed to external API."); } }
public async Task <Envelope <ExchangeDto> > GetExchanges(int pageNumber = 1) { // Call the external API using the product identifier as an URL parameter to string URL = "https://data.messari.io/api/v1/markets"; string urlParameters = "?fields=exchange_id,exchange_name,exchange_slug,quote_asset_symbol,price_usd,last_trade_at&page=" + pageNumber; HttpClient client = new HttpClient(); client.BaseAddress = new Uri(URL); // Add an Accept header for JSON format. client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); // List data response. var response = await client.GetAsync(urlParameters); if (response.IsSuccessStatusCode) { // Deserialize the response to a ExchangeDto model var exchanges = await HttpResponseMessageExtensions.DeserializeJsonToList <ExchangeDto>(response, true); // Create the enveloper var envelope = new Envelope <ExchangeDto> { Items = exchanges, PageNumber = pageNumber }; client.Dispose(); return(envelope); } else { throw new Exception("Request failed to external API."); } }
/// <remarks> /// Throws OperationCancelledException if <paramref name="cancel"/> is set. /// </remarks> private async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancel = default) { Guard.NotNull(nameof(request), request); // https://tools.ietf.org/html/rfc7230#section-2.7.1 // A sender MUST NOT generate an "http" URI with an empty host identifier. var host = Guard.NotNullOrEmptyOrWhitespace($"{nameof(request)}.{nameof(request.RequestUri)}.{nameof(request.RequestUri.DnsSafeHost)}", request.RequestUri.DnsSafeHost, trim: true); // https://tools.ietf.org/html/rfc7230#section-2.6 // Intermediaries that process HTTP messages (i.e., all intermediaries // other than those acting as tunnels) MUST send their own HTTP - version // in forwarded messages. request.Version = HttpProtocol.HTTP11.Version; if (TorSocks5Client != null && !TorSocks5Client.IsConnected) { TorSocks5Client?.Dispose(); TorSocks5Client = null; } if (TorSocks5Client == null || !TorSocks5Client.IsConnected) { TorSocks5Client = new TorSocks5Client(TorSocks5EndPoint); await TorSocks5Client.ConnectAsync(); await TorSocks5Client.HandshakeAsync(IsolateStream); await TorSocks5Client.ConnectToDestinationAsync(host, request.RequestUri.Port); Stream stream = TorSocks5Client.TcpClient.GetStream(); if (request.RequestUri.Scheme == "https") { SslStream sslStream; // On Linux and OSX ignore certificate, because of a .NET Core bug // This is a security vulnerability, has to be fixed as soon as the bug get fixed // Details: // https://github.com/dotnet/corefx/issues/21761 // https://github.com/nopara73/DotNetTor/issues/4 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { sslStream = new SslStream( stream, leaveInnerStreamOpen: true); } else { sslStream = new SslStream( stream, leaveInnerStreamOpen: true, userCertificateValidationCallback: (a, b, c, d) => true); } await sslStream .AuthenticateAsClientAsync( host, new X509CertificateCollection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, checkCertificateRevocation : true); stream = sslStream; } TorSocks5Client.Stream = stream; } cancel.ThrowIfCancellationRequested(); // https://tools.ietf.org/html/rfc7230#section-3.3.2 // A user agent SHOULD send a Content - Length in a request message when // no Transfer-Encoding is sent and the request method defines a meaning // for an enclosed payload body.For example, a Content - Length header // field is normally sent in a POST request even when the value is 0 // (indicating an empty payload body).A user agent SHOULD NOT send a // Content - Length header field when the request message does not contain // a payload body and the method semantics do not anticipate such a // body. if (request.Method == HttpMethod.Post) { if (request.Headers.TransferEncoding.Count == 0) { if (request.Content == null) { request.Content = new ByteArrayContent(new byte[] { }); // dummy empty content request.Content.Headers.ContentLength = 0; } else { if (request.Content.Headers.ContentLength == null) { request.Content.Headers.ContentLength = (await request.Content.ReadAsStringAsync()).Length; } } } } var requestString = await request.ToHttpStringAsync(); var bytes = Encoding.UTF8.GetBytes(requestString); await TorSocks5Client.Stream.WriteAsync(bytes, 0, bytes.Length); await TorSocks5Client.Stream.FlushAsync(); using (var httpResponseMessage = new HttpResponseMessage()) { return(await HttpResponseMessageExtensions.CreateNewAsync(TorSocks5Client.Stream, request.Method)); } }
public void GetTypeResult_WhenGivenNullArgument_ThrowArgumentNullException() { ArgumentNullException ex = Assert.Throws <ArgumentNullException>(() => HttpResponseMessageExtensions.GetTypedResult <WeatherDetail>(null)); Assert.NotNull(ex); }