3

I'm using https://currencylayer.com/documentation , Free account's currency conversion API. I let user input output currency, so for example if user input SGD, It'll display the currency conversion for USD to SGD:"USDSGD":1.318504 The way to grab that value is to use dynamic deserializer, and put it to a label. like so:

   lblResult.Text=test.quotes.USDSGD.ToString();

But what I want is to get the result regardless of the user selected currency. The other is always USD so I’d like to combine that and the user input currency to get the correct value from the API, like:

var propertyName = "USD" + destinationCurrencyName; // "USDSGD"
lblResult.Text=test.quotes.{propertyName}; // what I'd like

Here I would access the property "USDSGD".

I know that I can use reflection (Get property value from string using reflection in C#) but that seem to be overkill.

This is what the query returns:

{
  "success":true,
  "terms":"https:\/\/currencylayer.com\/terms",
  "privacy":"https:\/\/currencylayer.com\/privacy",
  "timestamp":1517629571,
  "source":"USD",
  "quotes":{
    "USDSGD":1.318504
  }
}

This is my code - strongly typed version indeed produces expected result, but I'd like to read name of currency (essentially property name of quotes element) from text box:

protected void btnConvert_Click(object sender, EventArgs e)
{
    string convertTo = TextBox1.Text.ToString();
    var webRequest = (HttpWebRequest)WebRequest.Create("http://apilayer.net/api/live?access_key=MY_ACCESS_KEY&currencies=" + Server.UrlEncode(convertTo) + "&source=USD&format=1");
    var webResponse = (HttpWebResponse)webRequest.GetResponse();
    if (webResponse.StatusCode == HttpStatusCode.OK)
    {
        JavaScriptSerializer json = new JavaScriptSerializer();
        StreamReader sr = new StreamReader(webResponse.GetResponseStream());
        var resString = sr.ReadToEnd();
        //var test = JsonConvert.DeserializeObject<Result>(resString);
        //lblResult.Text=test.quotes.USDSGD.ToString();
        var test2 = JsonConvert.DeserializeObject<dynamic>(resString);
        lblResult.Text = test2.quotes.USD+convertTo;
    }
}

Currently my code

var test2 = JsonConvert.DeserializeObject<dynamic>(resString);
        lblResult.Text = test2.quotes.USD+convertTo;

Returns the value:

SGD

Since the "convertTo" Variable happens to be "SGD".

I want the code to execute lblResult.Text = test2.quotes.USD+convertTo; not return me "convertTo" variable.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Tix
  • 449
  • 1
  • 8
  • 27
  • Your I put data has no property USD and as you write previously you used `USDSGD.ToString()` so why don’t you use that now also? – Sami Kuhmonen Feb 03 '18 at 06:39
  • @SamiKuhmonen The Query URL Goes like this: "http://apilayer.net/api/live?access_key=MY_ACCESS_KEY&currencies=" + Server.UrlEncode(convertTo) + "&source=USD&format=1" Whereby "convertTo" is the variable that user can change, USD is constant. Ultimately, what i want to get is lblResult.Text=test.quotes.USDSGD.ToString(); BUT doing this lblResult.Text=test.quotes.USD+convertTo.ToString(); Doesnt work – Tix Feb 03 '18 at 06:41
  • Yes, which has nothing to do with the result you get. Use a debugger. Look at the code on the top of this post you said was working. And then the code you’re using which doesn’t work. There’s no property `USD` so of course you get empty value + `convertTo` as output – Sami Kuhmonen Feb 03 '18 at 06:43
  • But if you’re trying to get a value of “USDSGD” then don’t use dynamics. Use JObject – Sami Kuhmonen Feb 03 '18 at 06:45

2 Answers2

5

Now that I understand your question, you’re trying to concatenation string for accessing a value, not concatenation value and currency.

This can’t be done with dynamic and there’s no need. Deserialize to JObject and use its properties to get the values:

var test2 = JObject.Parse(resString);
var value = (test2[“quotes”] as JObject)[“USD” + convertTo];

Note that this doesn’t check that the data is valid. value is a JToken you can get the value from.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • 1
    Since you understood question can you please [edit] the question so it matches your accepted answer? (Or update answer to clarify how it relates to ASP.Net prominently present in the title) – Alexei Levenkov Feb 03 '18 at 07:53
  • 1
    @AlexeiLevenkov Good idea, I edited it a bit and hopefully it is a bit more clear what they are after. – Sami Kuhmonen Feb 03 '18 at 07:56
2

You will want to use JObject to go through the response object:

var response = JObject.Parse(resString);
var quotes = response["quotes"];
lblResult.Text = quotes[ "USD" + convertTo ].Value<string>().ToString();

The indexers of JObject allow you to index directly by strings, which gives you the ability to dynamically select the correct property the users wants.

Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91