-1

I am making a UI where a user enters a stock symbol/ticker and presses a button to get data on the stock like open price, high, low, and closing price. I am using this all through the Alpha Vantage API. This link shows the JSON data of the API call I am using in this question on a daily basis for the last 100 days on the Microsoft stock. In order to get each of the last 100 business days (or weekdays: Monday-Friday) from today, I use this C# code:

public List<DateTime> GetDatesBetween(DateTime start, DateTime end, params DayOfWeek[] weekdays)
{
    bool allDays = weekdays == null || !weekdays.Any();
    var dates = Enumerable.Range(0, 1 + end.Subtract(start).Days)
                          .Select(offset => start.AddDays(offset))
                          .Where(d => allDays || weekdays.Contains(d.DayOfWeek))
                          .ToList();
    return dates;
}

And then I iterate through the list values of the GetDatesBetween() function, passing the properly-formatted dates in the JObject.Parse() method for retrieving the JSON from the RestSharp client's GET request:

using RestSharp;
using Newtonsoft.Json.Linq;
using FluentDateTime;

var client = new RestClient(String.Format("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={0}&apikey={1}", 
                            TextBox89.Text, "MY_API_KEY"));
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
List<DateTime> lst = GetDatesBetween(DateTime.Now.SubtractBusinessDays(100), DateTime.Now,
                     DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday);
foreach (var date in lst)
{
   var open = JObject.Parse(response.Content)["Time Series (Daily)"][date.ToString("yyyy-MM-dd")]["1. open"];
}

Except I keep getting "System.NullReferenceException: Object reference not set to an instance of an object" for this line:

var open = JObject.Parse(response.Content)["Time Series (Daily)"][date.ToString("yyyy-MM-dd")]["1. open"];

I checked the output of the date.ToString("yyyy-MM-dd") code, and it is in parallel with the format of the JSON from Alpha Vantage, like with today being "2020-01-12". I also tried putting in a date string myself, and it worked:

var open = JObject.Parse(response.Content)["Time Series (Daily)"]["2020-01-10"]["1. open"];

What am I doing wrong? Is there some syntax issue with the string? Sorry if this complex problem seems off-topic, but I'd really appreciate some help since this is getting awfully frustrating lately. Please refer to the link above on the JSON in order to help me with this issue.

Max Voisard
  • 1,685
  • 1
  • 8
  • 18
  • Break that monster expression into small subexpressions and look at them [in the debugger](https://stackoverflow.com/questions/4660142/). – Dour High Arch Jan 12 '20 at 22:57
  • @DourHighArch Possibly. If anything is null, it is my `JObject`, because I already debugged and found out that `date.ToString("yyyy-MM-dd")` does return a value. – Max Voisard Jan 12 '20 at 23:01
  • @MaxVoisard `JObject.Parse` is a static method. `JObject` cannot be null. Check if `response` or `response.Content` is null. – Ilian Jan 12 '20 at 23:13

1 Answers1

1

You never ever and never in a million years access a JObject properties like that. What if the property does not exist? It will throw exception. Which is what happening in your case. I ran a debugger and yeah. it has missing values. How can you be sure that the date time you are generating is actually in there? The least you could try is check for the values like this -

var theObj = JObject.Parse(response.Content.ReadAsStringAsync().Result); //ignore this line, I used the default HttpClient, so the proper way to read as string.
                if (theObj.TryGetValue("Time Series (Daily)", out var theSeries)) //check if key exists
                {
                    if (((JObject) theSeries).TryGetValue(date.ToString("yyyy-MM-dd"), out var dateValue)) //check if key exists
                    {
                        var open = dateValue["1. open"];
                    }
                }
brainless coder
  • 6,310
  • 1
  • 20
  • 36
  • Thank you, it worked. I feel a little stupid for my question now, although I thought every date returned from `GetDatesBetween()` corresponded to a date in Alpha Vantage's JSON. A simpler version of `TryGetValue()` would just be `if (value != null)`, but I like your implementation better. – Max Voisard Jan 13 '20 at 01:55