简体   繁体   English

如何使用C#使用POST方法获取JSON数据?

[英]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: 我正在尝试从BLS网站请求一组特定的数据:

http://www.bls.gov/developers/api_signature_v2.htm#parameters 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. 我非常接近,但是好像我的JSON发布请求未得到处理。

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. 我在JSON发布数据中进行了硬编码,以完全符合BLS链接上的示例显示的方式。 The issue is that it ignores all my parameters. 问题是它忽略了我所有的参数。 I'm only getting 3 years data despite asking for 5 etc... 尽管要求5等等,但我仅获得3年的数据...

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? 有人可以告诉我如何使用POST方法请求此数据吗? 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. 仅供参考,如果您要重新创建此问题,这将很容易,因为它们都是开放源数据等等。但是由于未在请求中看到我的授权,因此将用户每天限制为25个请求...因此,如果您按原样运行了26次...您将收到超出请求的消息。 If this gets working that goes from 25 times to 500. 如果成功,则从25倍变为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. 使用您的代码重新创建后,我能够取回RootObject类Results.Series集合中的有效数据。 First I created a new Class Called Series Post. 首先,我创建了一个新的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 从那里我修改了您的JSON序列化

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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