Google Currency Converter - c#

I had used this code in the last years however google seemed to have changed some of their links. For some reason I am getting this error message:
"Input string was not in a correct format."
in following line:
decimal rate = System.Convert.ToDecimal(match.Groups[1].Value);
My code:
try
{
WebClient web = new WebClient();
string url = string.Format("https://www.google.com/finance/converter?a={2}&from={0}&to={1}", fromCurrency.ToUpper(), toCurrency.ToUpper(), amount);
string response = web.DownloadString(url);
Regex regex = new Regex("rhs: \\\"(\\d*.\\d*)");
Match match = regex.Match(response);
decimal rate = System.Convert.ToDecimal(match.Groups[1].Value);
return rate;
}
catch
{
return 0;
}

You may not like this approach but it get's the job done.
WebClient web = new WebClient();
string url = string.Format("https://www.google.com/finance/converter?a={2}&from={0}&to={1}", fromCurrency.ToUpper(), toCurrency.ToUpper(), amount);
string response = web.DownloadString(url);
var split = response.Split((new string[] { "<span class=bld>"}),StringSplitOptions.None);
var value = split[1].Split(' ')[0];
decimal rate = decimal.Parse(value,CultureInfo.InvariantCulture);

Related

Retrieving data from an API

The first part of the program is to retrieve the employee user ID (or signature) from an API URL once the name has been entered. (Which I have done)
The second part, the user will enter a specific "to" and "from" date.
Using the signature obtained from the first part and the dates that the user enters, the program should pass this information to an API address and obtain information accordingly.
My question is that I am not sure how to pass the obtained signature to the new API address + the "to" and "from" date.
The first part of the program to retrieve the signature (works perfectly):
namespace TimeSheets_Try_11.Controllers
{
class WebAPI
{
public string Getsignature(string name)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlIora), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.UseDefaultCredentials = true;
string uri = "";
uri = StaticStrings.UrlIora + name;
var response = wc.DownloadString(uri);
var status = JsonConvert.DeserializeObject<List<Employeename>>(response);
string signame = status.Select(js => js.signature).First();
return signame;
}
The second part that I have written so far:
public string[] GetTime(double fromDate, double toDate, string username)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlNcert), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.UseDefaultCredentials = true;
string url = "";
url = StaticStrings.UrlNcert + username + "&fromDate=" + fromDate + "&toDate=" + toDate;
var respons = wc.DownloadString(url);
OracleHour ndata = JsonConvert.DeserializeObject<OracleHour>(respons);
var Get_Odnum = ndata.orderNumber;
var Dt_Work = ndata.dateOfWork;
var hrType = ndata.hourType;
var hr = ndata.hours;
var des = ndata.description;
var surname = ndata.surveyor;
string[] myncertdata = { Get_Odnum, Dt_Work.ToString(), hrType, hr.ToString(), des, surname };
return myncertdata;
}
}
}
The API strings:
namespace TimeSheets_Try_11.Controllers
{
class StaticStrings
{
public static string UrlIora = "https://iora.dnvgl.com/api/dictionary/employee/";
public static string UrlNcert = "https://cmcservices.dnvgl.com/Finance/api/oracleReportingCost?user=VERIT" + #"\";
}
}
For example if we are using the name "Jane Dow" from the date 9/22/20 - 9/29/20, the api strings will be
UrlIora = "https://iora.dnvgl.com/api/dictionary/employee/Jane
UrlNcert = "https://cmcservices.dnvgl.com/Finance/api/oracleReportingCost?user=VERIT\JDOW&fromDate=2020-09-22&toDate=2020-09-29"
Trivial way - change UrlNcert to url without query at first:
class StaticStrings
{
public static string UrlIora = "https://iora.dnvgl.com/api/dictionary/employee/";
public static string UrlNcert = "https://cmcservices.dnvgl.com/Finance/api/oracleReportingCost";
}
Then in your api call get values for username, fromDate and toDate and use string interpolation.
var url = $"{StaticStrings.UrlNcert}?user={username}&fromDate={fromDate:yyyy-MM-dd}&toDate={toDate:yyyy-MM-dd}";
If you want more complex way, check UriBuilder

c# Amazon Api request fail

I'm trying to create a HTTP url request to get Amazon items by its ASIN Array. I'm using the same code in my Objective-c code for the same reason and it's work perfectly.
But i'm getting this messeage everytime i try to access the url in my chrome:
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
This is the code i'm using:
private void GetFinalUrlForAsinArray(ArrayList asinArr)
{
String timeStamp = GetTimeStamp();
String amazonAPIUrl = "http://webservices.amazon.com/onca/xml?";
ArrayList param = new ArrayList();
param.Add("AWSAccessKeyId=myawsaccesskeyid");
param.Add("AssociateTag=myassociatetag");
param.Add("IdType=ASIN");
param.Add(string.Join(",", asinArr.ToArray()));
param.Add("Operation=ItemLookup");
param.Add("ResponseGroup=ItemAttributes,Offers");
param.Add("Service=AWSECommerceService");
param.Add(String.Format("Timestamp={0}", timeStamp));
amazonAPIUrl += string.Join("&", param.ToArray());
string queryString = new System.Uri(amazonAPIUrl).Query;
var queryDictionary = HttpUtility.ParseQueryString(queryString);
ArrayList queryItemsNew = new ArrayList();
foreach (var query in queryDictionary)
{
String name = HttpUtility.UrlEncode((string)query);
String value = HttpUtility.UrlEncode((string)queryDictionary.Get((string)query));
queryItemsNew.Add(String.Format("{0}={1}", name,value));
}
String path = string.Join("&", queryItemsNew.ToArray());
String finalPath = String.Format("GET\nwebservices.amazon.com\n/onca/xml\n{0}",path);
string signature = HmacSha256Digest(finalPath);
String finalUrl = String.Format("http://webservices.amazon.com/onca/xml?{0}&Signature={1}", path, signature);
}
private String GetTimeStamp()
{
DateTime d = DateTime.UtcNow;
String str = d.ToString("yyyy-MM-dd''T''HH:mm:ss''Z''");
return str;
}
private static string HmacSha256Digest(string message)
{
UTF8Encoding encoding = new UTF8Encoding();
HMACSHA256 hmac = new HMACSHA256(encoding.GetBytes(mysecret));
string signature = Convert.ToBase64String(hmac.ComputeHash(encoding.GetBytes(message)));
String sigEncoded = Uri.EscapeDataString(signature);
return sigEncoded;
}
Having had a look at the API documentation it looks like you've missed the ItemId key here:
param.Add(string.Join(",", asinArr.ToArray()));
I'm guessing you meant it to be:
param.Add("ItemId=" + string.Join(",", asinArr.ToArray()));
It otherwise looks to comply with the spec, the only other thing I noted was the example had the URL encoding as uppercase i.e. %3A rather than the C# default %3a.

C# String.Format doesn't place a variable in the respective placeholder

I have got some code in here that getting world currency exchanges from net. But in following code, this line
private double GetConvertedCurrencyValue(string inputCurrency, string outputCurrency, double value)
{
string request = String.Format("http://www.xe.com/ucc/convert.cgi?Amount={0}&From={1}&To={2}", value, inputCurrency, outputCurrency);
System.Net.WebClient wc = new System.Net.WebClient();
string apiResponse = wc.DownloadString(request); // This is a blocking operation.
wc.Dispose();
string header = String.Format("XE.com: {0} to {2} rate:",inputCurrency, outputCurrency);
apiResponse = apiResponse.Replace(header, "");
string outValue = apiResponse.Split('=')[1];
outValue = outValue.Replace(outputCurrency, "");
return Double.Parse(outValue, System.Globalization.CultureInfo.InvariantCulture);
}
was error. What can I do?
In this line of code you have:
string header = String.Format("XE.com: {0} to {2} rate:",inputCurrency, outputCurrency);
It should be:
string header = String.Format("XE.com: {0} to {1} rate:",inputCurrency, outputCurrency);

C# Get Current Exchange Rate from XE

I need to display current exchange rates on my application.
Is it possible to retrieve the exchange rate from http://www.xe.com (XE Converter)
Here what I tried:
public string CurrencyConversion(decimal amount, string fromCurrency, string toCurrency)
{
string Output = "";
string fromCurrency1 = comboBox1.Text;
string toCurrency1 = comboBox2.Text;
decimal amount1 = Convert.ToDecimal(textBox1.Text);
// For other currency symbols see http://finance.yahoo.com/currency-converter/
// Construct URL to query the Yahoo! Finance API
const string urlPattern = "http://finance.yahoo.com/d/quotes.csv?s={0}{1}=X&f=l1";
string url = string.Format(urlPattern, fromCurrency1, toCurrency1);
// Get response as string
string response = new WebClient().DownloadString(url);
// Convert string to number
decimal exchangeRate =
decimal.Parse(response, System.Globalization.CultureInfo.InvariantCulture);
// Output the result
Output = (amount1 * exchangeRate).ToString();
textBox2.Text = Output;
return Output;
}
With this code I am not having the full output... the decimal part is notshowing...
Yes XE offers an API but it is paid only.
Making an automated tool to extract the data is not allowed. (source)
I tried your code and it is working for me. What do you exactly mean with the decimal part is not showing ?
public string CurrencyConversion(decimal amount, string fromCurrency, string toCurrency)
{
string url = string.Format(urlPattern, fromCurrency, toCurrency);
using (var wc = new WebClient())
{
var response = wc.DownloadString(url);
decimal exchangeRate = decimal.Parse(response, CultureInfo.InvariantCulture);
return (amount * exchangeRate).ToString("N3");
}
}
TestCode:
Console.WriteLine($"$ 5 = € {CurrencyConversion(5m, "USD", "EUR")}");
Console.WriteLine($"£ 20 = $ {CurrencyConversion(20m, "GBP", "USD")}");
Result:
$ 5 = € 4,661
£ 20 = $ 25,616
EDIT
Get Newtonsoft.Json using NuGet
PM> Install-Package Newtonsoft.Json
Code:
private const string urlPattern = "http://rate-exchange-1.appspot.com/currency?from={0}&to={1}";
public string CurrencyConversion(decimal amount, string fromCurrency, string toCurrency)
{
string url = string.Format(urlPattern, fromCurrency, toCurrency);
using (var wc = new WebClient())
{
var json = wc.DownloadString(url);
Newtonsoft.Json.Linq.JToken token = Newtonsoft.Json.Linq.JObject.Parse(json);
decimal exchangeRate = (decimal)token.SelectToken("rate");
return (amount * exchangeRate).ToString();
}
}

How to get redirect from HttpWebResponse?

I am trying to get a redirect from Google Maps using a project that is currently only at .Net Framework 4.0.
Take Microsoft's mailing address as an example:
1 Microsoft Way, Redmond, WA
Format a string that replaces Spaces , Commas , with Plus + signs:
https://www.google.com/maps?daddr=1+microsoft+way+redmond+wa
By the time Google finishes processing the page, the final URL has the Latitude and Longitude:
https://www.google.com/maps/dir//1+Microsoft+Way,+Redmond,+WA+98052/#47.6393095,-122.1327333,16z/data=!3m1!4b1!4m8!4m7!1m0!1m5!1m1!1s0x54906d73f7de150b:0x922499d19305e9a0!2m2!1d-122.1283559!2d47.6393096
I need the Latitude and Longitude from this URL.
I found this article already on SO:
Get a collection of redirected URLs from HttpWebResponse
Using the solution there, I created this very similar looking method:
private String latitude, longitude;
private void GetLatLongFromAddress(String p_street_name, String p_city, String p_state, String p_postal_code)
{
var street_name = String.Format("{0}", p_street_name.Replace(' ', '+')).Trim();
var city = String.Format("{0}", p_city).Trim();
var state = String.Format("{0}", p_state).Trim();
var postal_code = String.Format("{0}", p_postal_code).Trim();
var mapUrl = String.Format("http://maps.google.com/?daddr={0}+{1}+{2}+{3}",
street_name, city, state, postal_code);
var location = String.Copy(mapUrl);
while (!String.IsNullOrEmpty(location))
{
var req1 = (HttpWebRequest)HttpWebRequest.Create(location);
req1.AllowAutoRedirect = false;
// give page time to redirect?
// System.Threading.Thread.Sleep(5000);
using (var resp = (HttpWebResponse)req1.GetResponse())
{
location = resp.GetResponseHeader("Location");
if (!String.IsNullOrEmpty(location))
{
var postalIndex = location.IndexOf(postal_code);
var slashAtIndex = location.IndexOf("/#") + 1;
if ((postalIndex < slashAtIndex) && (slashAtIndex < location.Length))
{
var split = location.Substring(slashAtIndex).Split(',');
latitude = split[0];
longitude = split[1];
}
}
}
}
}
You can see where I format the original URL with this line:
var mapUrl = String.Format("http://maps.google.com/?daddr={0}+{1}+{2}+{3}",
street_name, city, state, postal_code);
The problem is with this line:
location = resp.GetResponseHeader("Location");
Every time I get the response, the returned location value is the same as the mapUrl value that I started with because Google does not redirect it immediately.
I tried adding a Sleep(5000) call, but that did not change anything.
How would I go about getting the final redirect?

Categories

Resources