2

I am trying to request a specific set of data from the BLS website:

http://www.bls.gov/developers/api_signature_v2.htm#parameters

on that link I'm specifically trying to get one series with optional parameters. I am super close but it's as if my JSON post request isn't being processed.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Net;
using System.Data.SqlClient;
using System.Web;
using System.Configuration;
using System.Data;
using System.Globalization;
using System.ComponentModel;
using Newtonsoft.Json;
using System.Web.Script.Serialization;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;



namespace ConsoleApplication5
{


//Classes needed to deserialze JSON data (JSON to C# website)
public class DataObject
{
    public string Name { get; set; }
}

public class Footnote
{
}

public class Datum
{
    public string year { get; set; }
    public string period { get; set; }
    public string periodName { get; set; }
    public string value { get; set; }
    public List<Footnote> footnotes { get; set; }

}

public class Series
{
    public string seriesID { get; set; }
    public List<Datum> data { get; set; }


}

public class Results
{
    public List<Series> series { get; set; }
}

public class RootObject
{
    public string status { get; set; }
    public int responseTime { get; set; }
    public List<object> message { get; set; }
    public Results Results { get; set; }

    public override string ToString()
    {
        return string.Format("Status: {0}", status);
    }

}

class Program
{

    static double octLY;
    static double oct2y;

    static void Main(string[] args)
    {
        TryParsing();

    }


    static void TryParsing()
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.bls.gov/publicAPI/v2/timeseries/data/CUUR0000SA0");
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            //string json = new JavaScriptSerializer().Serialize(new
            //{
            //    seriesid = "CUUR0000SA0",
            //    startYear = "2010",
            //    endYear = "2015",
            //    catalog = "true",
            //    calculations = "true",
            //    annualAverage = "true",
            //    registrationKey = "f3171173a8ce4b969b5085ba9a83202f"


            //});

            string json = "{\"seriesid\":[\"CUUR0000SA0\"],\"startyear\":\"2010\",\"endyear\":\"2015\",\"catalog\":true,\"calculations\":true,\"annualAverage\":true,\"registrationKey\":\"f3171173a8ce4b969b5085ba9a83202f\"}";

            //Console.WriteLine(json.ToString());
            //Console.ReadLine();

            streamWriter.Write(json);
            streamWriter.Flush();
            streamWriter.Close();
        }

        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
            var result = streamReader.ReadToEnd();
            Console.WriteLine(result.ToString());
            Console.ReadLine();
            }
        }

    }
}

I hardcoded in the JSON post data to conform to EXACTLY how the example on the BLS link shows. The issue is that it ignores all my parameters. I'm only getting 3 years data despite asking for 5 etc...

It is fine to use my auth code as this is generic and will be changed later.

Could someone show me how to request this data using the POST method? I feel like I am just missing something elementary here but can't get it.

FYI, if you are re-creating this issue, it will be easy as it's all open source data etc... but since it's not seeing my authorization in the request, it's limiting the user to 25 requests per day... so if you run this 26 times as is... you will get a request exceeded message. If this gets working that goes from 25 times to 500.

here is my other method that I was trying:

static void TryParse()
    {
        //Get JSON data
        using (WebClient wc = new WebClient())
        {
            var json = wc.DownloadString("http://api.bls.gov/publicAPI/v2/timeseries/data/CUUR0000SA0");

            //Deserialize JSON data
            var p1 = new JavaScriptSerializer();
            RootObject j = p1.Deserialize<RootObject>(json);

            RootObject r1 = JsonConvert.DeserializeObject<RootObject>(json);


            //check to see if JSON data was successfully downloaded
            if (r1.ToString() == "Status: REQUEST_SUCCEEDED")
            {

                //Loop through the JSON to find values
                foreach (Datum d in j.Results.series[0].data)
                {
                    //Filters data based on year value
                    if ((Int16.Parse(d.year) == DateTime.Now.Year - 1 && d.period == "M10" )) //|| (Int16.Parse(d.year) == DateTime.Now.Year - 1 && d.period == "M10" )))
                    {
                        octLY = (double.Parse(d.value));
                        Console.WriteLine("OCT14: {0}", octLY);

                        //Console.WriteLine(d.year + " : " + d.period + " : " + d.periodName + " : " + d.value);
                    }

                    if (Int16.Parse(d.year) == DateTime.Now.Year - 2 && d.period == "M10")
                    {
                        oct2y = (double.Parse(d.value));
                        Console.WriteLine("OCT13: {0}", oct2y);

                    }
                    else { }
                }

                Console.WriteLine("CPI: {0}", (octLY - oct2y) / oct2y + 1);
            }

            else
            {
                Console.WriteLine(r1.ToString());
                Console.ReadLine();
            }


            Console.ReadLine();
        }

    }
6
  • I dont think your seriesid should be appended to the url you are attempting to post to since its contained within the JSON payload. That's one issue I am seeing, when I recreated your code I get back a 0 results message based on the information you are supplying. Commented Dec 14, 2015 at 17:11
  • I have removed it but still only get the last 3 years... It doesn't seem to have any effect on my end as far as what I get from the site.... I get JSON data but it's not the criteria I'm posting. Commented Dec 14, 2015 at 17:14
  • I think also in your json annualAverage should be annualaverage notice the caps A in the first one. When I corrected that I received data. Commented Dec 14, 2015 at 17:15
  • Also as a side note I created a Class called SeriesPost with public properties that matched your JSON object. Its easier to populate the class and use JSON.net to serialize it to string JSON instead of having to make sure you get all the correct escapes in your JSON string. Will also make it easier to make this code a little more dynamic. Commented Dec 14, 2015 at 17:18
  • I have used JSON.net in another method... and is why it's in the using statement... I'm not partial to either way,... just whatever will get me 5 years of data... the return we are all getting is a generic that you could get without using the post method. Commented Dec 14, 2015 at 17:25

1 Answer 1

3

Recreating using your code I was able to get back valid data in my RootObject Class Results.Series collection. First I created a new Class Called Series Post.

public class SeriesPost 
{
    public string[] seriesid { get; set; }
    public string startyear { get; set; }
    public string endyear { get; set; }
    public bool catalog { get; set; }
    public bool calculations { get; set; }
    public bool annualaverage { get; set; }
    public string registrationKey { get; set; }
}

From there I modified your JSON serilalization a bit

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
        string newJson = Newtonsoft.Json.JsonConvert.SerializeObject(new SeriesPost()
        {
            seriesid = (new List<string>() { "CUUR0000SA0" }).ToArray(),
            startyear = "2010",
            endyear = "2015",
            catalog = false,
            calculations = true,
            annualaverage = true,
            registrationKey = "f3171173a8ce4b969b5085ba9a83202f"

        });
        //So you can see the JSON thats output
        System.Diagnostics.Debug.WriteLine(newJson);
        streamWriter.Write(newJson);
        streamWriter.Flush();
        streamWriter.Close();
   }
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
            //Here your RootObject is the Type thats returned with your results
            RootObject obj = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(result);
            // Loop over the series in the results
            foreach(Series ser in obj.Results.series)
            {
                // Loop over the Data in each of the series.
                foreach(var data in ser.data)
                {
                    //Output the year, in my test I got multiple entries for each year between 2010 to 2015
                    Console.WriteLine(data.year);
                } 
            }
            Console.ReadLine();
        }
Sign up to request clarification or add additional context in comments.

Comments

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.