Link to home
Start Free TrialLog in
Avatar of 11ptMan
11ptMan

asked on

How do I Pass JSON Payload with WebClient in C#

I'm fairly new to web services. I've used them before but in all the cases so far all the request data was passed in the url.  I'm trying to work with a web service now and have run in to a new situation. In one case the data is passed in the url and I was successful in writting a routine to consume it.  But the other one has me stumped. I've done several searches with little resolve. Basicly I need to know how to add a payload to the JSON request.( See Notes in source code below). The BLS site provided some assitance but I'm using the WebClient in VS2010 and can't find the equivilent to this part of their Apache HTTP Commons Client example:
 

StringEntity input = new StringEntity("{\"seriesid\":[\"LAUCN040010000000005\", \"LAUCN040010000000006\"]}");
input.setContentType("application/json");
postRequest.setEntity(input);


Do I need to switch away from the WebClient Object and use the HttpWebRequest object to have this work?


Here is the code in my test app

 using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;

namespace Test
{

    class Program
    {
        private static string BLSPublicDataS = "http://api.bls.gov/publicAPI/v1/timeseries/data/{0}";
        private static string BLSPublicDataM = "http://api.bls.gov/publicAPI/v1/timeseries/data/";


        //Single Series Signature
        /// <summary>
        /// Returns single series of data from the Bureau of Labor Statistics Web Site 
        /// </summary>
        /// <param name="Series">Specific Series for which data is desired</param>
        /// <returns>returns BSLData object populated with values returned</returns>
        public static string GetBRSData(string Series)
        //Debug Notes: This information provided in the API examples on the site 
        //Single Series
        //HTTP Type: GET
        //URL: http://api.bls.gov/publicAPI/v1/timeseries/data/<series_id>
        //Payload: series_id
        //Example Payload: LAUCN040010000000005 
        
        {
            string serviceUrl = string.Format(BLSPublicDataS, Series);
            // Synchronous Consumption  
            var syncClient = new WebClient();
            syncClient.Headers["Content-type"] = "application/json";
            var content = syncClient.DownloadString(serviceUrl);
            var myBLSData = new ConsoleApplication1.BLSData();
            //Console.Write(content.ToString());
            //// Create the Json serializer and parse the response 
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ConsoleApplication1.BLSData));
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
            {
                myBLSData = (ConsoleApplication1.BLSData)serializer.ReadObject(ms);
            }
            return content.ToString();
        }


        //Clues from the BLS Site 
        //Apache HTTP Commons Client:
        //The HttpPost HttpGet class can be used to connect to the BLS Public Data API via Apache HTTP Commons Client, as shown in the following example. Remember to include JSON as the ContentType.
        // HttpPost httpPost = new HttpPost("http://api.bls.gov/publicAPI/v1/timeseries/data/");
        //StringEntity input = new StringEntity("{\"seriesid\":[\"LAUCN040010000000005\", \"LAUCN040010000000006\"]}");
        //input.setContentType("application/json");
        //postRequest.setEntity(input);
        //HttpResponse response = httpClient.execute(postRequest);
        //variableFoo = response.getEntity().getContent()

        // Multi Series Signature 
        /// <summary>
        /// Returns multiple series of data from the Bureau of Labor Statistics Web Site 
        /// </summary>
        /// <param name="Series">Multiple Series for which data is desired (up to 25) Series1,Series2 </param>
        /// <returns>returns collection of BSLData objects populated with values returned</returns>
        public static string GetBRSData(string Series1, string Series2)
        //Use this signature to retrieve data for more than one timeseries for the past three years. You can include up to 25 series IDs, each //separated with a comma, in the body of your request.
        //HTTP Type: POST
        //URL: http://api.bls.gov/publicAPI/v1/timeseries/data/
        //Payload: JSON Payload:
        //{"seriesid":["Series1", ..., "SeriesN"]} 
        //Example Payload: {"seriesid":["LAUCN040010000000005", "LAUCN040010000000006"]} 

        {
            //string inputData = string.Format("{\"seriesid\":[\"{0}\",\"{1}\"]}", Series1, Series2);
            // DebugNote: The above does not generate the Payload exactly but then the below doesn't either. 
            // DebugNote: Learn more about quoting strings in a string. \" should work but it doesn't seam to. 
            //string inputPayload = "{\"seriesid\":[\"LAUCN040010000000005\", \"LAUCN040010000000006\"]}"; 
            //Try this 
            string jsonPayload = "{" + "\"seriesid\":[" + "\"LAUCN040010000000005" + "\"," + "\"LAUCN040010000000006" + "\"]}";
            // still get "{\"seriesid\":[\"LAUCN040010000000005\",\"LAUCN040010000000006\"]}"
            
            string serviceUrl = BLSPublicDataM; 
            var syncClient = new WebClient();
            syncClient.Headers["Content-type"]="application/json";
            // I'm thinking something has to go here to add the inputPayload to the "Body" of the request.
            <WHAT GOES HERE to include the jsonPayload string (once i fix it) with the request?> 

            var content = syncClient.DownloadString(serviceUrl);
            Console.Write(content.ToString());
            //// Create the Json serializer and parse the response 
            //DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ConsoleApplication1.BLSData));
            //using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
            //{
            //    myBLSData = (ConsoleApplication1.WeatherData)serializer.ReadObject(ms);
            //}
            return content.ToString();

        }

        static void Main(string[] args)
        {
            Console.Write("Try a single request");
            string test = GetBRSData("LAUCN040010000000005");
            Console.Write(test);
            Console.ReadKey();
            Console.Write("Now the Multiple request");
            string test2 = GetBRSData("LAUCN040010000000005","LAUCN040010000000006");
            Console.WriteLine("End ");
        }

    }
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of kaufmed
kaufmed
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
P.S.

I forgot to mention: I included the JSON.NET parser into the above code. Really it's up to you which parse you use so long as you turn your object into a string that you then pass to the GetBytes method. JSON.NET parser is a very simple to use library, though, IMO.
Avatar of 11ptMan
11ptMan

ASKER

Thank you, your solution works and enabled me to find the explanations I was looking for.  The key learning for me was I was using download when upload was the correct choice.