5

I am trying to convert JSON data into objects of a C# class and display the values into a console program. My console window comes up blank each time I run it, I believe the problem is within CurrencyRates class but I am very new to this and unsure. Any help would be appreciated!!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json;



namespace Cooper_Lab12
{
    class Program
    {
        static void Main(string[] args)
        {


            var currencyRates = _download_serialized_json_data<CurrencyRates>("https://openexchangerates.org/api/latest.json?app_id=4be3cf28d6954df2b87bf1bb7c2ba47b");

            Console.Read();
        }


        private static T _download_serialized_json_data<T>(string url) where T : new()
        {


            //var currencyRates = _download_serialized_json_data<CurrencyRates>(url);
            using (var w = new WebClient())
            {

                var json_data = string.Empty;
                // attempt to download JSON data as a string
                try
                {
                    json_data = w.DownloadString("https://openexchangerates.org/api/latest.json?app_id=4be3cf28d6954df2b87bf1bb7c2ba47b ");
                }
                catch (Exception) { }
                // if string with JSON data is not empty, deserialize it to class and return its instance 
                return !string.IsNullOrEmpty(json_data) ? JsonConvert.DeserializeObject<T>(json_data) : new T();
            }


        }
        public class RootObject
        {
            public string Disclaimer { get; set; }
            public string License { get; set; }
            public int Timestamp { get; set; }
            public string Base { get; set; }
            public Dictionary<string, decimal> Rates { get; set; }
        }

    }
}

and here is my CurrencyRates class:

public class CurrencyRates
{
    public string Disclaimer { get; set; }
    public string License { get; set; }
    public int TimeStamp { get; set; }
    public string Base { get; set; }
    public Dictionary<string, decimal> Rates { get; set; }
}
3
  • 1
    Currently it doesn't look as though you're writing to the console, which would be one reason it is blank. Could you try Console.Write(currencyRates) within your Main function? Commented Apr 29, 2017 at 4:57
  • If I add the into my Main, the console output is now:Cooper_Lab12.CurrencyRates Commented Apr 29, 2017 at 5:01
  • 1
    Okay, that is the expected value since your _download_serialized_json_data actually returns a de-serialized object. You can loop over the Rates property and write to the console as the user Christos suggested in the answer. Commented Apr 29, 2017 at 5:08

2 Answers 2

5

Your code works. However, you don't try to output result to the console. That's why you don't see anything.

If you add the following to your Main method after the currencyRates, you will see the values that have been retrieved.

Console.WriteLine($"{currencyRates.Disclaimer}");
Console.WriteLine($"{currencyRates.License}");
Console.WriteLine($"{currencyRates.TimeStamp}");
Console.WriteLine($"{currencyRates.Base}");
foreach (var currencyRatesRate in currencyRates.Rates)
{
    Console.WriteLine($"Key: {currencyRatesRate.Key}, Value: {currencyRatesRate.Value}");
}

Notes

Generally, it is better you follow standard naming conventions so that the readers of your code can quickly catch up on what is going on. For instance, all method names are written in Pascal Case. Use meaningful naming for your variables. For instance webClient is more meaningful than w. The variable names are written in Camel Case. E.g json_data should be renamed in jsonData.

Avoid having many empty lines in your code. It would be far easier for the reader of your code to focus on a few lines and read your code. Last but not least, you declare a parameter for your method of type string and you never use it. This parameter should be used instead of the hard-coded string in the DownloadString method.

Compare this refactored method with the one we had initially:

private static T DownloadAndDeserializeJsonData<T>(string url) where T : new()
{
    using (var webClient = new WebClient())
    {
        var jsonData = string.Empty;
        try
        {
            jsonData = webClient.DownloadString(url);
        }
        catch (Exception) { }

        return string.IsNullOrEmpty(jsonData) 
                   ? new T()
                   : JsonConvert.DeserializeObject<T>(jsonData);
    }
}

If you want a central place for naming guidelines for .NET Framework and C#, you could have a look here.

Sign up to request clarification or add additional context in comments.

15 Comments

Thanks for the help! I added your code but now I am getting am unhandled NullReferenceException on currencyRates.Rates
You are welcome. Actually I ran your code twice having added the Console.WriteLine.... and I didn't notice that.
hmm, that is weird! the program keeps breaking a the NullReferenceExceptiom and I'm at a loss of how to fix it
@ecooper10 It's seems a bit weird. Have you tried to debug it. Go to the line you call DownloadString... and press F9 a red mark should be appeared at the left. Then press F5. You program will start to run and very quickly it would stop at the line with the red mark. Then press F10 and hover with your mouse over the variable json_data (or jsonData, if you have refactored the method). What's the value? Furthermore, if you navigate to openexchangerates.org/api/… from your browser don't you see the json you expect to be downloaded?
@ecooper10 Did you press F10? If yes then a yellow arrow would be appeared below the breakpoint. At this point if you hover over your variable you should see a string value there.
|
0

I believe Microsoft's Http libraries are not very developer friendly & therefore would like to propose an alternative & much easier way to do the above using the free & open-source ServiceStack.Text library.

    static void Main(string[] args)
    {
        // ret API url
        string url = "https://openexchangerates.org/api/latest.json?app_id=4be3cf28d6954df2b87bf1bb7c2ba47b";

        // GET Json data from api & map to CurrencyRates
        var todo =  url.GetJsonFromUrl().FromJson<CurrencyRates>();

        // print result to screen
        todo.PrintDump();
    }
    public class CurrencyRates
    {
        public string Disclaimer { get; set; }
        public string License { get; set; }
        public int TimeStamp { get; set; }
        public string Base { get; set; }
        public Dictionary<string, decimal> Rates { get; set; }
    }

This is a much more concise / readable / maintainable way of getting the data from your external API.

You can achieve this by simply installing the Nuget package ServiceStack.Text; by running

Install-Package ServiceStack.Text 

in your NuGet Package console manager.

1 Comment

Maybe that was the case back then but now a days await client.GetFromJsonAsync<> works great without extra packages

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.