ePossum
ePossum

Reputation: 45

Get second level values from JSON string using C# and using a foreach

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

Answers (3)

Rui Jarimba
Rui Jarimba

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:

Deserialized object

Upvotes: 1

Mihir Dave
Mihir Dave

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

go..
go..

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

Related Questions