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

11ptManAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

käµfm³d 👽Commented:
Here is an example of sending and receiving JSON via WebClient. "Accept" headers specify what format you want to get back; "Content-Type" headers specify what format you are sending.

using System;
using System.Net;
using System.Text;

namespace _28498682
{
    class Program
    {
        static void Main(string[] args)
        {
            // http://www.bls.gov/developers/api_signature.htm#multiple
            string apiUrl = "http://api.bls.gov/publicAPI/v1/timeseries/data/";
            var data = new { seriesid = new[] { "LAUCN040010000000005", "LAUCN040010000000006" } };
            string requestJson = Newtonsoft.Json.JsonConvert.SerializeObject(data);
            string responseJson = string.Empty;

            using (WebClient client = new WebClient())
            {
                client.Headers[HttpRequestHeader.Accept] = "application/json";
                client.Headers[HttpRequestHeader.ContentType] = "application/json";

                byte[] response = client.UploadData(apiUrl, Encoding.UTF8.GetBytes(requestJson));

                responseJson = Encoding.UTF8.GetString(response);
            }

            Console.WriteLine(responseJson);
        }
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
käµfm³d 👽Commented:
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.
0
11ptManAuthor Commented:
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Services

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.