简体   繁体   中英

How to use 'POST' method to get JSON data using c#?

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();
        }

    }

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();
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM