Reputation: 45
Complete Novice to JSON - this is my first foray into JSON with C#.
I have a single record returned from an HTTP get request.
var exchRateData = Get($"https://api.exchangeratesapi.io/2018-10-30?base=EUR&symbols=AUD");
Returns :
{"date":"2018-10-30","rates":{"AUD":1.6025},"base":"EUR"}
.
The AUD and 1.6025 values are both variables in the GET request. So the GET request can be for SGD or INR in which it returns:
{"date":"2018-10-30","rates":{"SGD":0.0187977737},"base":"INR"}
Always ONE record with levels is returned like those two examples above.
What I would like is to access the values of the second level values,
i.e {"AUD":1.6025} or {"SGD":0.0187977737}
I have tried:
var jsonResult = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(exchRateData);
foreach (var keyValue in jsonResult)
{
try
{
LblGetValues.Text = LblGetValues.Text + "Key: " + keyValue.Key + " Value:" + keyValue.Value + "<br>";
if (keyValue.Key == "date")
LblDate.Text = keyValue.Value;
//This is where I get stuck.
if (keyValue.Key == "rates")
{
// I would like to be able to do this here :
//string currencyCode = "AUD" (or "SGD" if second GET request)
//double currencyRate = 1.6025 (or 0.0187977737 if second GET request)
//JArray secondLevel = new JArray("rates");
// LblRate.Text = keyValue.Value.ToString();
}
if (keyValue.Key == "base")
LblBase.Text = keyValue.Value;
}
catch (Exception errMsg)
{
LblMsg.Text = errMsg.Message + errMsg.StackTrace;
}
}
Please help....
Upvotes: 4
Views: 2486
Reputation: 18094
The accepted solution works fine if there is only one rate (which is what the OP wants), but it won't work with more than 1 rate. Also, it adds extra complexity, which can be avoided by using a Dictionary
(see below).
Example - the following request (AUD
, USD
, GBP
)
https://api.exchangeratesapi.io/2018-10-30?base=EUR&symbols=AUD,USD,GBP
Will return the following json:
{"date":"2018-10-30","rates":{"USD":1.1372,"GBP":0.89148,"AUD":1.6025},"base":"EUR"}
You can use the following C# class to deserialize your json string:
public class ExchangeRate
{
[JsonProperty("date")]
public string Date { get; set; }
[JsonProperty("rates")]
public Dictionary<string, decimal> Rate { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
}
Deserializing the json string:
string json = @"{""date"":""2018-10-30"",""rates"":{""USD"":1.1372,""GBP"":0.89148,""AUD"":1.6025},""base"":""EUR""}";
ExchangeRate rate = JsonConvert.DeserializeObject<ExchangeRate>(json);
Result:
Upvotes: 1
Reputation: 4024
I would suggest using JSON.NET
Here you will deserialize your JSON string into your c# model class
your model class will look like this Model Generated using json2csharp
public class Rates
{
[JsonProperty(PropertyName = "fieldName")]
public double currency { get; set; }
}
public class RootObject
{
public string date { get; set; }
public Rates rates { get; set; }
public string @base { get; set; }
}
Then this is how you deserialize it using JSON.NET
// THis works for normal secanario but it won't work for you
var exchangeRates = JsonConvert.DeserializeObject<RootObject>("Your Json String goes here");
But then your JSON scenario is bit complex so you have to use CustomContractResolver
Here is Example for that
ContractResolver class
internal class CustomContractResolver : DefaultContractResolver
{
public CustomContractResolver(string fieldName)
{
FieldName = fieldName;
}
public string FieldName { get; set; }
protected override string ResolvePropertyName(string propertyName)
{
return propertyName == "fieldName" ? FieldName : base.ResolvePropertyName(propertyName);
}
}
how to use this setting
var settings = new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ContractResolver = new CustomContractResolver("Pass Your currency here")
};
// Make Http Calls here and replace returned string in below method
var data = JsonConvert.DeserializeObject<RootObject>("Your JSON String", setting);
// Here You can access your currency rates
double currencyRate = data.currency;
Upvotes: 2
Reputation: 948
public class Rates
{
public double AUD { get; set; }
}
public class ObjectCurrency
{
public string date { get; set; }
public Rates rates { get; set; }
public string @base { get; set; }
}
var data= JsonConvert.DeserializeObject<ObjectCurrency>(exchRateData);
Upvotes: 0