Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 17778
  • Last Modified:

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

0
11ptMan
Asked:
11ptMan
  • 2
1 Solution
 
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
 
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

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now